GainPool - Smart Contract Audit Report
Summary
GainPool is building a new yield farming platform where users can earn rewards in the form of the project's native GainCoin token.
Notes on the Token Contract:The initial total supply of the GainCoin token is 10 trillion [10,000,000,000,000] $GAIN. Any user can burn their own tokens to reduce the total supply. The contract utilizes a Minter role. Any assigned Minter address has the ability to mint any amount of tokens to any address at any time. Although a Pauser role exists, it is never used within the contract. The token complies with the ERC20 standard. As the project is implemented with Solidity v0.8.0 it is protected from overflows.
Notes on the Staking Contract:The owner has the ability to utilize this contract to create a staking pool. Users can stake their $GAIN tokens into the pool to earn $GAIN token rewards. The team must exercise caution as to properly set the staking token and reward token as the $GAIN token. Users can claim rewards when making a deposit to or a withdrawal from the contract. There is no fee associated with making a deposit or withdrawal. Users can also manually claim all of their rewards via the claim() function. The owner has the ability to update the rewards per block to any value greater than zero at any time. The contract features an owner-specific function called destroy() that was not properly set by the team. This function will need to be properly set or removed as the contract cannot be deployed in its current state. The contract utilizes SafeMath (and similarily safe functions) to prevent overflows.
Audit Findings Summary:
- No security issues from outside attackers were identified.
- Please ensure trust in the team as they have some control in the ecosystem.
- The team must properly set or remove the destroy() function in order for the staking contract to be deployable.
- Date: October 19th, 2021
Combined External Threat Results
Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | N/A | PASS |
Delegate Call to Untrusted Contract | N/A | PASS |
Dependence on Predictable Variables | N/A | PASS |
Deprecated Opcodes | N/A | PASS |
Ether Thief | N/A | PASS |
Exceptions | N/A | PASS |
External Calls | N/A | PASS |
Integer Over/Underflow | N/A | PASS |
Logical Issues | Staking Contract does not compile | FAIL |
Multiple Sends | N/A | PASS |
Suicide | N/A | PASS |
State Change External Calls | N/A | PASS |
Unchecked Retval | N/A | PASS |
User Supplied Assertion | N/A | PASS |
Critical Solidity Compiler | N/A | PASS |
Overall Contract Safety | PASS |
Details: GainPool- Token Contract
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Int] IERC20Metadata (IERC20)
- [Ext] name
- [Ext] symbol
- [Ext] decimals
+ Context
- [Int] _msgSender
- [Int] _msgData
+ ERC20 (Context, IERC20, IERC20Metadata)
- [Pub] #
- [Pub] name
- [Pub] symbol
- [Pub] decimals
- [Pub] totalSupply
- [Pub] maxAmount
- [Pub] balanceOf
- [Pub] transfer #
- [Pub] allowance
- [Pub] approve #
- [Pub] transferFrom #
- [Pub] increaseAllowance #
- [Pub] decreaseAllowance #
- [Int] _transfer #
- [Int] _mint #
- [Int] _burn #
- [Int] _approve #
- [Int] _beforeTokenTransfer #
- [Int] _afterTokenTransfer #
+ ERC20Burnable (Context, ERC20)
- [Pub] burn #
- [Pub] burnFrom #
+ Pausable (Context)
- [Pub] #
- [Pub] paused
- [Int] _pause #
- modifiers: whenNotPaused
- [Int] _unpause #
- modifiers: whenPaused
+ ERC20Pausable (ERC20, Pausable)
- [Int] _beforeTokenTransfer #
+ [Int] IAccessControl
- [Ext] hasRole
- [Ext] getRoleAdmin
- [Ext] grantRole #
- [Ext] revokeRole #
- [Ext] renounceRole #
+ [Int] IAccessControlEnumerable (IAccessControl)
- [Ext] getRoleMember
- [Ext] getRoleMemberCount
+ [Lib] Strings
- [Int] toString
- [Int] toHexString
- [Int] toHexString
+ [Int] IERC165
- [Ext] supportsInterface
+ ERC165 (IERC165)
- [Pub] supportsInterface
+ AccessControl (Context, IAccessControl, ERC165)
- [Pub] supportsInterface
- [Pub] hasRole
- [Int] _checkRole
- [Pub] getRoleAdmin
- [Pub] grantRole #
- modifiers: onlyRole
- [Pub] revokeRole #
- modifiers: onlyRole
- [Pub] renounceRole #
- [Int] _setupRole #
- [Int] _setRoleAdmin #
- [Prv] _grantRole #
- [Prv] _revokeRole #
+ [Lib] EnumerableSet
- [Prv] _add #
- [Prv] _remove #
- [Prv] _contains
- [Prv] _length
- [Prv] _at
- [Prv] _values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
+ AccessControlEnumerable (IAccessControlEnumerable, AccessControl)
- [Pub] supportsInterface
- [Pub] getRoleMember
- [Pub] getRoleMemberCount
- [Pub] grantRole #
- [Pub] revokeRole #
- [Pub] renounceRole #
- [Int] _setupRole #
+ ERC20PresetMinterPauser (Context, AccessControlEnumerable, ERC20Burnable, ERC20Pausable)
- [Pub] #
- modifiers: ERC20
- [Pub] mint #
- [Pub] pause #
- [Pub] unpause #
- [Int] _beforeTokenTransfer #
+ Gain (ERC20PresetMinterPauser)
- [Pub] #
- modifiers: ERC20PresetMinterPauser
Details: GainPool- Staking Contract
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ Context
- [Int] _msgSender
- [Int] _msgData
+ Ownable (Context)
- [Pub] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Lib] SafeMath
- [Int] tryAdd
- [Int] trySub
- [Int] tryMul
- [Int] tryDiv
- [Int] tryMod
- [Int] add
- [Int] sub
- [Int] mul
- [Int] div
- [Int] mod
- [Int] sub
- [Int] div
- [Int] mod
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Int] functionDelegateCall #
- [Int] functionDelegateCall #
- [Prv] _verifyCallResult
+ [Lib] SafeERC20
- [Int] safeTransfer #
- [Int] safeTransferFrom #
- [Int] safeApprove #
- [Int] safeIncreaseAllowance #
- [Int] safeDecreaseAllowance #
- [Prv] _callOptionalReturn #
+ Stake (Ownable)
- [Ext] setTokens #
- modifiers: onlyOwner
- [Ext] startPool #
- modifiers: onlyOwner
- [Ext] pendingRewards
- [Int] updatePool #
- [Ext] deposit #
- [Ext] withdraw #
- [Ext] claim #
- [Int] safeTokenTransfer #
- [Ext] setRewardPerBlock #
- modifiers: onlyOwner
- [Ext] destroy #
- modifiers: onlyOwner