Skip to content

Commit

Permalink
addressing audit remarks and adding graphics
Browse files Browse the repository at this point in the history
  • Loading branch information
kupermind committed Oct 23, 2024
1 parent fda1740 commit e5eb2de
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 7 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,26 @@ The audit is provided as development matures. The latest audit report can be fou
- Create staking proxy instance on [Launch](https://launch.olas.network/);
- Vote for staking contracts on [Govern](https://govern.olas.network/).

## Contribute Architecture
```mermaid
flowchart LR
Deployer -- deploy --> Contributors
Deployer -- deploy --> ContributorsProxy
Deployer -- deploy --> ContributeManager
Deployer -- deploy --> ContributeActivityChecker
Deployer -- changeManager --> ContributorsProxy --> Contributors
Deployer -- setContributeAgentStatuses --> ContributorsProxy
Deployer -- changeOwner --> ContributorsProxy
User -- createAndStake --> ContributeManager -- setServiceInfoForId --> ContributorsProxy
User -- stake --> ContributeManager
User -- unstake --> ContributeManager
User -- claim --> ContributeManager
User -- checkpoint --> StakingInstance -- getNonces --> ContributeActivityChecker -- mapMutisigActivities --> ContributorsProxy
ContributeManager -- mint --> StakingRegistryL2
ContributeManager -- stake --> StakingInstance
ContributeManager -- unstake --> StakingInstance
Agent -- increaseActivity --> ContributorsProxy
```

## Acknowledgements
The staking programmes contracts were inspired and based on the following sources:
Expand Down
3 changes: 3 additions & 0 deletions audits/internal1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ more CEI,
IContributors(contributorsProxy).setServiceInfoForId(msg.sender, 0, 0, address(0), address(0));
```
[x] Fixed

2. cyclic initialize(address _manager)
```
Remove params in proxy init() / or setup manage as msg.sender.
```
[x] Fixed


47 changes: 42 additions & 5 deletions contracts/contribute/ContributeManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {ERC721TokenReceiver} from "../../lib/autonolas-registries/lib/solmate/sr
import {IContributors} from "./interfaces/IContributors.sol";
import {IService} from "./interfaces/IService.sol";
import {IStaking} from "./interfaces/IStaking.sol";
import {IToken} from "./interfaces/IToken.sol";
import {IToken, INFToken} from "./interfaces/IToken.sol";

// Multisig interface
interface IMultisig {
Expand All @@ -20,6 +20,9 @@ error ZeroAddress();
/// @dev Zero value.
error ZeroValue();

/// @dev Caught reentrancy violation.
error ReentrancyGuard();

/// @dev Service is already created and staked for the contributor.
/// @param socialId Social Id.
/// @param serviceId Service Id.
Expand Down Expand Up @@ -87,7 +90,9 @@ contract ContributeManager is ERC721TokenReceiver {
address public immutable fallbackHandler;

// Nonce
uint256 internal nonce;
uint256 internal _nonce;
// Reentrancy lock
uint256 internal _locked = 1;

/// @dev ContributeManager constructor.
/// @param _contributorsProxy Contributors proxy address.
Expand Down Expand Up @@ -164,15 +169,15 @@ contract ContributeManager is ERC721TokenReceiver {
IService(serviceManager).registerAgents{value: NUM_AGENT_INSTANCES}(serviceId, instances, agentIds);

// Prepare Safe multisig data
uint256 localNonce = nonce;
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),
randomNonce, "0x");
// Deploy the service
multisig = IService(serviceManager).deploy(serviceId, safeMultisig, data);

// Update the nonce
nonce = localNonce + 1;
_nonce = localNonce + 1;
}

/// @dev Stakes the already deployed service.
Expand All @@ -185,7 +190,7 @@ contract ContributeManager is ERC721TokenReceiver {
IContributors(contributorsProxy).setServiceInfoForId(msg.sender, socialId, serviceId, multisig, stakingInstance);

// Approve service NFT for the staking instance
IToken(serviceRegistry).approve(stakingInstance, serviceId);
INFToken(serviceRegistry).approve(stakingInstance, serviceId);

// Stake the service
IStaking(stakingInstance).stake(serviceId);
Expand All @@ -196,6 +201,12 @@ contract ContributeManager is ERC721TokenReceiver {
/// @param socialId Contributor social Id.
/// @param stakingInstance Contribute staking instance address.
function createAndStake(uint256 socialId, address stakingInstance) external payable {
// Reentrancy guard
if (_locked > 1) {
revert ReentrancyGuard();
}
_locked = 2;

// Check for zero value
if (socialId == 0) {
revert ZeroValue();
Expand Down Expand Up @@ -246,13 +257,21 @@ contract ContributeManager is ERC721TokenReceiver {
_stake(socialId, serviceId, multisig, stakingInstance);

emit CreatedAndStaked(socialId, msg.sender, serviceId, multisig, stakingInstance);

_locked = 1;
}

/// @dev Stakes the already deployed service.
/// @param socialId Social Id.
/// @param serviceId Service Id.
/// @param stakingInstance Staking instance.
function stake(uint256 socialId, uint256 serviceId, address stakingInstance) external {
// Reentrancy guard
if (_locked > 1) {
revert ReentrancyGuard();
}
_locked = 2;

// Check for existing service corresponding to the msg.sender
(, uint256 serviceIdCheck, address multisig, ) = IContributors(contributorsProxy).mapSocialIdServiceInfo(msg.sender);
if (serviceIdCheck > 0) {
Expand All @@ -276,10 +295,18 @@ contract ContributeManager is ERC721TokenReceiver {
_stake(socialId, serviceId, multisig, stakingInstance);

emit Staked(socialId, msg.sender, serviceId, multisig, stakingInstance);

_locked = 1;
}

/// @dev Unstakes service Id corresponding to the msg.sender and clears the contributor record.
function unstake() external {
// Reentrancy guard
if (_locked > 1) {
revert ReentrancyGuard();
}
_locked = 2;

// Check for existing service corresponding to the social Id
(uint256 socialId, uint256 serviceId, address multisig, address stakingInstance) =
IContributors(contributorsProxy).mapSocialIdServiceInfo(msg.sender);
Expand All @@ -298,11 +325,19 @@ contract ContributeManager is ERC721TokenReceiver {
IContributors(contributorsProxy).setServiceInfoForId(msg.sender, 0, 0, address(0), address(0));

emit Unstaked(socialId, msg.sender, serviceId, multisig, stakingInstance);

_locked = 1;
}

/// @dev Claims rewards for the service corresponding to msg.sender.
/// @return reward Staking reward.
function claim() external returns (uint256 reward) {
// Reentrancy guard
if (_locked > 1) {
revert ReentrancyGuard();
}
_locked = 2;

// Check for existing service corresponding to the social Id
(uint256 socialId, uint256 serviceId, address multisig, address stakingInstance) =
IContributors(contributorsProxy).mapSocialIdServiceInfo(msg.sender);
Expand All @@ -314,5 +349,7 @@ contract ContributeManager is ERC721TokenReceiver {
reward = IStaking(stakingInstance).claim(serviceId);

emit Claimed(socialId, msg.sender, serviceId, multisig, stakingInstance);

_locked = 1;
}
}
1 change: 1 addition & 0 deletions contracts/contribute/Contributors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ contract Contributors {

// Traverse all contribute agents and statuses
for (uint256 i = 0; i < contributeAgents.length; ++i) {
// Check for zero addresses
if (contributeAgents[i] == address(0)) {
revert ZeroAddress();
}
Expand Down
13 changes: 11 additions & 2 deletions contracts/contribute/interfaces/IToken.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

// Token interface
// ERC20 token interface
interface IToken {
/// @dev Transfers the token amount.
/// @param to Address to transfer to.
Expand All @@ -19,5 +19,14 @@ interface IToken {
/// @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
/// @param spender Account address that will be able to transfer tokens on behalf of the caller.
/// @param amount Token amount.
function approve(address spender, uint256 amount) external;
/// @return True if the function execution is successful.
function approve(address spender, uint256 amount) external returns (bool);
}

// ERC721 token interface
interface INFToken {
/// @dev Sets token `id` as the allowance of `spender` over the caller's tokens.
/// @param spender Account address that will be able to transfer the token on behalf of the caller.
/// @param id Token id.
function approve(address spender, uint256 id) external;
}

0 comments on commit e5eb2de

Please sign in to comment.