From a43e44fafad9987526af7ee36fa24399a20b5a6e Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 23 Oct 2024 11:33:26 +0100 Subject: [PATCH] refactor: staking verifier --- .../contribute/ContributeActivityChecker.sol | 2 +- ...rviceManager.sol => ContributeManager.sol} | 104 ++++++++++++------ contracts/contribute/Contributors.sol | 8 +- contracts/contribute/interfaces/IStaking.sol | 5 + 4 files changed, 84 insertions(+), 35 deletions(-) rename contracts/contribute/{ContributeServiceManager.sol => ContributeManager.sol} (78%) diff --git a/contracts/contribute/ContributeActivityChecker.sol b/contracts/contribute/ContributeActivityChecker.sol index c4a69d9..7c343a5 100644 --- a/contracts/contribute/ContributeActivityChecker.sol +++ b/contracts/contribute/ContributeActivityChecker.sol @@ -46,7 +46,7 @@ contract ContributeActivityChecker { /// @return nonces Set of a single service multisig nonce. function getMultisigNonces(address multisig) external view virtual returns (uint256[] memory nonces) { nonces = new uint256[](1); - // The nonces are equal to the social off-chain activity corresponding multisig activity + // The nonce is equal to the social off-chain activity corresponding to a multisig activity nonces[0] = IContributors(contributorsProxy).mapMutisigActivities(multisig); } diff --git a/contracts/contribute/ContributeServiceManager.sol b/contracts/contribute/ContributeManager.sol similarity index 78% rename from contracts/contribute/ContributeServiceManager.sol rename to contracts/contribute/ContributeManager.sol index 144e049..21a8b79 100644 --- a/contracts/contribute/ContributeServiceManager.sol +++ b/contracts/contribute/ContributeManager.sol @@ -45,12 +45,12 @@ error ServiceNotDefined(uint256 socialId); /// @param serviceOwner Actual service owner. error ServiceOwnerOnly(uint256 serviceId, address sender, address serviceOwner); -/// @title ContributeServiceManager - Smart contract for managing services for contributors +/// @title ContributeManager - Smart contract for managing services for contributors /// @author Aleksandr Kuperman - /// @author Andrey Lebedev - /// @author Tatiana Priemova - /// @author David Vilela - -contract ContributeServiceManager { +contract ContributeManager { event CreatedAndStaked(uint256 indexed socialId, address indexed serviceOwner, uint256 serviceId, address indexed multisig, address stakingInstance); event Staked(uint256 indexed socialId, address indexed serviceOwner, uint256 serviceId, @@ -60,18 +60,26 @@ contract ContributeServiceManager { event Claimed(uint256 indexed socialId, address indexed serviceOwner, uint256 serviceId, address indexed multisig, address stakingInstance); - // Contribute agent Id - uint256 public constant AGENT_ID = 6; - // Contributor service config hash mock - bytes32 public constant CONFIG_HASH = 0x0000000000000000000000000000000000000000000000000000000000000006; - // Contributors proxy contract address + // Number of agent instances + uint256 public constant NUM_AGENT_INSTANCES = 1; + // Threshold + uint256 public constant THRESHOLD = 1; + // Contributor agent Id + uint256 public immutable agentId; + // Contributor service config hash + bytes32 public immutable configHash; + // Contributors proxy address address public immutable contributorsProxy; - // Service manager contract address + // Service manager address address public immutable serviceManager; + // OLAS token address + address public immutable olas; // Service registry address address public immutable serviceRegistry; // Service registry token utility address address public immutable serviceRegistryTokenUtility; + // Staking factory address + address public immutable stakingFactory; // Safe multisig processing contract address address public immutable safeMultisig; // Safe fallback handler @@ -80,20 +88,43 @@ contract ContributeServiceManager { // Nonce uint256 internal nonce; - /// @dev ContributeServiceManager constructor. + /// @dev ContributeManager constructor. /// @param _contributorsProxy Contributors proxy address. /// @param _serviceManager Service manager address. + /// @param _olas OLAS token address. + /// @param _stakingFactory Staking factory address. /// @param _safeMultisig Safe multisig address. /// @param _fallbackHandler Multisig fallback handler address. - constructor(address _contributorsProxy, address _serviceManager, address _safeMultisig, address _fallbackHandler) { + /// @param _agentId Contributor agent Id. + /// @param _configHash Contributor service config hash. + constructor( + address _contributorsProxy, + address _serviceManager, + address _olas, + address _stakingFactory, + address _safeMultisig, + address _fallbackHandler, + uint256 _agentId, + bytes32 _configHash + ) { // Check for zero addresses - if (_contributorsProxy == address(0) || _serviceManager == address(0) || _safeMultisig == address(0) || - _fallbackHandler == address(0)) { + if (_contributorsProxy == address(0) || _serviceManager == address(0) || _olas == address(0) || + _stakingFactory == address(0) || _safeMultisig == address(0) || _fallbackHandler == address(0)) { revert ZeroAddress(); } + // Check for zero values + if (_agentId == 0 || _configHash == 0) { + revert ZeroValue(); + } + + agentId = _agentId; + configHash = _configHash; + contributorsProxy = _contributorsProxy; serviceManager = _serviceManager; + olas = _olas; + stakingFactory = _stakingFactory; safeMultisig = _safeMultisig; fallbackHandler = _fallbackHandler; serviceRegistry = IService(serviceManager).serviceRegistry(); @@ -103,42 +134,39 @@ contract ContributeServiceManager { /// @dev Creates and deploys a service for the contributor. /// @param token Staking token address. /// @param minStakingDeposit Min staking deposit value. - /// @param numAgentInstances Number of agent instances in the service. - /// @param threshold Threshold. /// @return serviceId Minted service Id. /// @return multisig Service multisig. function _createAndDeploy( address token, - uint256 minStakingDeposit, - uint256 numAgentInstances, - uint256 threshold + uint256 minStakingDeposit ) internal returns (uint256 serviceId, address multisig) { // Set agent params - IService.AgentParams[] memory agentParams = new IService.AgentParams[](1); - agentParams[0] = IService.AgentParams(uint32(numAgentInstances), uint96(minStakingDeposit)); + IService.AgentParams[] memory agentParams = new IService.AgentParams[](NUM_AGENT_INSTANCES); + agentParams[0] = IService.AgentParams(uint32(NUM_AGENT_INSTANCES), uint96(minStakingDeposit)); // Set agent Ids - uint32[] memory agentIds = new uint32[](1); - agentIds[0] = uint32(AGENT_ID); + uint32[] memory agentIds = new uint32[](NUM_AGENT_INSTANCES); + agentIds[0] = uint32(agentId); // Set agent instances as [msg.sender] - address[] memory instances = new address[](1); + address[] memory instances = new address[](NUM_AGENT_INSTANCES); instances[0] = msg.sender; // Create a service owned by this contract - serviceId = IService(serviceManager).create(address(this), token, CONFIG_HASH, agentIds, - agentParams, uint32(threshold)); + serviceId = IService(serviceManager).create(address(this), token, configHash, agentIds, + agentParams, uint32(THRESHOLD)); // Activate registration (1 wei as a deposit wrapper) IService(serviceManager).activateRegistration{value: 1}(serviceId); // Register msg.sender as an agent instance (numAgentInstances wei as a bond wrapper) - IService(serviceManager).registerAgents{value: numAgentInstances}(serviceId, instances, agentIds); + IService(serviceManager).registerAgents{value: NUM_AGENT_INSTANCES}(serviceId, instances, agentIds); // Prepare Safe multisig data uint256 localNonce = nonce; + uint256 randomNonce = uint256(keccak256(abi.encodePacked(block.timestamp, msg.sender, localNonce))); bytes memory data = abi.encodePacked(address(0), fallbackHandler, address(0), address(0), uint256(0), - localNonce, "0x"); + randomNonce, "0x"); // Deploy the service multisig = IService(serviceManager).deploy(serviceId, safeMultisig, data); @@ -167,15 +195,29 @@ contract ContributeServiceManager { /// @param socialId Contributor social Id. /// @param stakingInstance Contribute staking instance address. function createAndStake(uint256 socialId, address stakingInstance) external payable { + // Check for zero value + if (socialId == 0) { + revert ZeroValue(); + } + // Check for existing service corresponding to the social Id (uint256 serviceId, address multisig, , ) = IContributors(contributorsProxy).mapSocialIdServiceInfo(socialId); if (serviceId > 0) { revert ServiceAlreadyStaked(socialId, serviceId, multisig); } + // Check for staking instance validity + if(!IStaking(stakingFactory).verifyInstance(stakingInstance)) { + revert WrongStakingInstance(stakingInstance); + } + // Get the token info from the staking contract // If this call fails, it means the staking contract does not have a token and is not compatible address token = IStaking(stakingInstance).stakingToken(); + // Check the token address + if (token != olas) { + revert WrongStakingInstance(stakingInstance); + } // Get other service info for staking uint256 minStakingDeposit = IStaking(stakingInstance).minStakingDeposit(); @@ -183,20 +225,20 @@ contract ContributeServiceManager { uint256 threshold = IStaking(stakingInstance).threshold(); // Check for number of agent instances that must be equal to one, // since msg.sender is the only service multisig owner - if (numAgentInstances != 1 || threshold != 1) { + if (numAgentInstances != NUM_AGENT_INSTANCES || threshold != THRESHOLD) { revert WrongStakingInstance(stakingInstance); } // Calculate the total bond required for the service deployment: - uint256 totalBond = (1 + numAgentInstances) * minStakingDeposit; + uint256 totalBond = (1 + NUM_AGENT_INSTANCES) * minStakingDeposit; // Transfer the total bond amount from the contributor - IToken(token).transferFrom(msg.sender, address(this), totalBond); + IToken(olas).transferFrom(msg.sender, address(this), totalBond); // Approve token for the serviceRegistryTokenUtility contract - IToken(token).approve(serviceRegistryTokenUtility, totalBond); + IToken(olas).approve(serviceRegistryTokenUtility, totalBond); // Create and deploy service - (serviceId, multisig) = _createAndDeploy(token, minStakingDeposit, numAgentInstances, threshold); + (serviceId, multisig) = _createAndDeploy(olas, minStakingDeposit); // Stake the service _stake(socialId, serviceId, multisig, stakingInstance); diff --git a/contracts/contribute/Contributors.sol b/contracts/contribute/Contributors.sol index 0b23b05..02becea 100644 --- a/contracts/contribute/Contributors.sol +++ b/contracts/contribute/Contributors.sol @@ -47,7 +47,7 @@ contract Contributors { event ManagerUpdated(address indexed manager); event SetServiceInfoForId(uint256 indexed socialId, uint256 indexed serviceId, address multisig, address stakingInstance, address indexed serviceOwner); - event SetContributeAgentStatuses(address[] mechMarketplaces, bool[] statuses); + event SetContributeAgentStatuses(address[] contributeAgents, bool[] statuses); event MultisigActivityChanged(address indexed senderAgent, address[] multisigs, uint256[] activityChanges); // Version number @@ -170,7 +170,7 @@ contract Contributors { /// @dev Sets contribute agent statues. /// @param contributeAgents Contribute agent addresses. /// @param statuses Corresponding whitelisting statues. - function setMechMarketplaceStatuses(address[] memory contributeAgents, bool[] memory statuses) external { + function setContributeAgentStatuses(address[] memory contributeAgents, bool[] memory statuses) external { // Check for the ownership if (msg.sender != owner) { revert OwnerOnly(msg.sender, owner); @@ -181,7 +181,7 @@ contract Contributors { revert WrongArrayLength(contributeAgents.length, statuses.length); } - // Traverse all the mech marketplaces and statuses + // Traverse all contribute agents and statuses for (uint256 i = 0; i < contributeAgents.length; ++i) { if (contributeAgents[i] == address(0)) { revert ZeroAddress(); @@ -214,4 +214,6 @@ contract Contributors { emit MultisigActivityChanged(msg.sender, multisigs, activityChanges); } + + } \ No newline at end of file diff --git a/contracts/contribute/interfaces/IStaking.sol b/contracts/contribute/interfaces/IStaking.sol index 5cdcbc2..778412c 100644 --- a/contracts/contribute/interfaces/IStaking.sol +++ b/contracts/contribute/interfaces/IStaking.sol @@ -32,4 +32,9 @@ interface IStaking { /// @param serviceId Service Id. /// @return Staking reward. function claim(uint256 serviceId) external returns (uint256); + + /// @dev Verifies a service staking contract instance. + /// @param instance Service staking proxy instance. + /// @return True, if verification is successful. + function verifyInstance(address instance) external view returns (bool); }