Skip to content

Commit

Permalink
Merge pull request #50 from valory-xyz/service3
Browse files Browse the repository at this point in the history
refactor: creating mechs in marketplace
  • Loading branch information
DavidMinarsch authored Dec 13, 2024
2 parents 7d32ead + 1300039 commit 6d37c92
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 167 deletions.
56 changes: 0 additions & 56 deletions contracts/AgentFactory.sol

This file was deleted.

39 changes: 0 additions & 39 deletions contracts/AgentMech.sol
Original file line number Diff line number Diff line change
Expand Up @@ -288,23 +288,6 @@ contract AgentMech is OlasMech {
emit Deliver(msg.sender, requestId, requestData);
}

/// @dev Registers a request without a marketplace.
/// @notice Interface provided for backwards compatibility only.
/// @param data Self-descriptive opaque data-blob.
/// @return requestId Request Id.
function request(bytes memory data) external payable returns (uint256 requestId) {
if (mechMarketplace != address(0)) {
revert MarketplaceExists(mechMarketplace);
}

// Get the local request Id
requestId = getRequestId(msg.sender, data, mapNonces[msg.sender]);
mapNonces[msg.sender]++;

// Perform a request
_request(msg.sender, data, requestId);
}

/// @dev Registers a request by a marketplace.
/// @notice This function is called by the marketplace contract since this mech was specified as a priority one.
/// @param account Requester account address.
Expand Down Expand Up @@ -342,28 +325,6 @@ contract AgentMech is OlasMech {
emit RevokeRequest(account, requestId);
}

/// @dev Delivers a request without a marketplace.
/// @notice Interface provided for backwards compatibility only.
/// @param requestId Request id.
/// @param data Self-descriptive opaque data-blob.
function deliver(uint256 requestId, bytes memory data) external onlyOperator {
// Reentrancy guard
if (_locked > 1) {
revert ReentrancyGuard();
}
_locked = 2;

// Check for the marketplace existence
if (mechMarketplace != address(0)) {
revert MarketplaceExists(mechMarketplace);
}

// Request delivery
_deliver(requestId, data);

_locked = 1;
}

/// @dev Delivers a request by a marketplace.
/// @notice This function ultimately calls mech marketplace contract to finalize the delivery.
/// @param requestId Request id.
Expand Down
41 changes: 41 additions & 0 deletions contracts/MechFactoryBasic.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {AgentMech} from "./AgentMech.sol";

/// @title Mech Factory Basic - Periphery smart contract for managing basic mech creation
contract MechFactoryBasic {
event CreateBasicMech(address indexed mech, uint256 indexed serviceId, uint256 indexed price);

// Agent factory version number
string public constant VERSION = "0.1.0";

/// @dev Registers service as a mech.
/// @param mechMarketplace Mech marketplace address.
/// @param serviceRegistry Service registry address.
/// @param serviceId Service id.
/// @param payload Mech creation payload.
/// @return mech The created mech instance address.
function createMech(
address mechMarketplace,
address serviceRegistry,
uint256 serviceId,
bytes memory payload
) external returns (address mech) {
// Check payload length
if (payload.length != 32) {
revert();
}

// Decode price
uint256 price = abi.decode(payload, (uint256));

// Get salt
bytes32 salt = keccak256(abi.encode(block.timestamp, msg.sender, serviceId));

// Service multisig is isOperator() for the mech
mech = address((new AgentMech){salt: salt}(serviceRegistry, serviceId, price, mechMarketplace));

emit CreateBasicMech(mech, serviceId, price);
}
}
39 changes: 34 additions & 5 deletions contracts/MechMarketplace.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ import {IMech} from "./interfaces/IMech.sol";
import {IServiceRegistry} from "./interfaces/IServiceRegistry.sol";
import {IStaking, IStakingFactory} from "./interfaces/IStaking.sol";

interface IMechFactory {
/// @dev Registers service as a mech.
/// @param mechMarketplace Mech marketplace address.
/// @param serviceRegistry Service registry address.
/// @param serviceId Service id.
/// @param payload Mech creation payload.
/// @return mech The created mech instance address.
function createMech(address mechMarketplace, address serviceRegistry, uint256 serviceId, bytes memory payload)
external returns (address mech);
}

// Mech delivery info struct
struct MechDelivery {
// Priority mech address
Expand All @@ -21,10 +32,7 @@ struct MechDelivery {

/// @title Mech Marketplace - Marketplace for posting and delivering requests served by agent mechs
contract MechMarketplace is IErrorsMarketplace {
event OwnerUpdated(address indexed owner);
event FactoryUpdated(address indexed factory);
event MinMaxResponseTimeoutUpdated(uint256 minResponseTimeout, uint256 maxResponseTimeout);
event MechRegistrationStatusChanged(address indexed mech, bool status);
event CreateMech(address indexed mech, uint256 indexed serviceId);
event MarketplaceRequest(address indexed requester, address indexed requestedMech, uint256 requestId, bytes data);
event MarketplaceDeliver(address indexed priorityMech, address indexed actualMech, address indexed requester,
uint256 requestId, bytes data);
Expand All @@ -37,7 +45,7 @@ contract MechMarketplace is IErrorsMarketplace {
}

// Contract version number
string public constant VERSION = "1.0.0";
string public constant VERSION = "1.1.0";
// Domain separator type hash
bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH =
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
Expand Down Expand Up @@ -133,6 +141,21 @@ contract MechMarketplace is IErrorsMarketplace {
);
}

/// @dev Registers service as a mech.
/// @param serviceId Service id.
/// @param mechFactory Mech factory address.
/// @return mech The created mech instance address.
function create(uint256 serviceId, address mechFactory, bytes memory payload) external returns (address mech) {
mech = IMechFactory(mechFactory).createMech(address(this), serviceRegistry, serviceId, payload);

// This should never be the case
if (mech == address(0)) {
revert ZeroAddress();
}

emit CreateMech(mech, serviceId);
}

/// @dev Registers a request.
/// @notice The request is going to be registered for a specified priority agent mech.
/// @param data Self-descriptive opaque data-blob.
Expand Down Expand Up @@ -395,6 +418,12 @@ contract MechMarketplace is IErrorsMarketplace {
revert ZeroValue();
}

// Check marketplace address
address checkMarketplace = IMech(mech).mechMarketplace();
if (checkMarketplace != address(this)) {
revert UnauthorizedAccount(checkMarketplace);
}

// Check mech service Id and staking instance, if applicable
multisig = checkServiceAndGetMultisig(mechStakingInstance, mechServiceId);

Expand Down
67 changes: 0 additions & 67 deletions contracts/integrations/nevermined/AgentFactorySubscription.sol

This file was deleted.

44 changes: 44 additions & 0 deletions contracts/integrations/nevermined/MechFactorySubscription.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {AgentMechSubscription} from "./AgentMechSubscription.sol";

/// @title Mech Factory Subscription - Periphery smart contract for managing subscription mech creation
contract MechFactorySubscription {
event CreateSubscriptionMech(address indexed mech, uint256 indexed serviceId, uint256 minCreditsPerRequest,
address indexed subscriptionNFT, uint256 subscriptionTokenId);

// Agent factory version number
string public constant VERSION = "0.1.0";

/// @dev Registers service as a mech.
/// @param mechMarketplace Mech marketplace address.
/// @param serviceRegistry Service registry address.
/// @param serviceId Service id.
/// @param payload Mech creation payload.
/// @return mech The created mech instance address.
function createMech(
address mechMarketplace,
address serviceRegistry,
uint256 serviceId,
bytes memory payload
) external returns (address mech) {
// Check payload length
if (payload.length != 96) {
revert();
}

// Decode subscription parameters
(uint256 minCreditsPerRequest, address subscriptionNFT, uint256 subscriptionTokenId) =
abi.decode(payload, (uint256, address, uint256));

// Get salt
bytes32 salt = keccak256(abi.encode(block.timestamp, msg.sender, serviceId));

// Service multisig is isOperator() for the mech
mech = address((new AgentMechSubscription){salt: salt}(serviceRegistry, serviceId, minCreditsPerRequest,
subscriptionNFT, subscriptionTokenId, mechMarketplace));

emit CreateSubscriptionMech(mech, serviceId, minCreditsPerRequest, subscriptionNFT, subscriptionTokenId);
}
}
4 changes: 4 additions & 0 deletions contracts/interfaces/IMech.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ interface IMech {
/// @notice Only marketplace can call this function if the request is not delivered by the chosen priority mech.
/// @param requestId Request Id.
function revokeRequest(uint256 requestId) external;

/// @dev Gets mech marketplace address.
/// @return marketplace Mech Marketplace address.
function mechMarketplace() external view returns (address marketplace);
}

0 comments on commit 6d37c92

Please sign in to comment.