Good Games Guild - Audit Report
Good Games Guild is building a new yield farming platform.
For this audit, we analyzed Good Games Guild's MasterChef contract at commit f2570d7fbd36f9d02f08223efe0f872e0e552ca1 on the team's private Github Repository.
Notes on the Contract:
- Users can stake various tokens in this contract to earn rewards in the form of the project's native $GGG token.
- There is a fee associated with making a deposit to the contract, set by the team upon adding the pool. The fee is directed to the team's dev wallet.
- There is also a tax fee that is used to take into account the taxes from fee-on-transfer tokens. However, this is not best practice as the owner of the fee-on-transfer token may have the ability to exempt the Masterchef contract from fees (or alter fee percentages) to exploit the contract.
- We strongly discourage the use of any fee-on-transfer (and ERC777-compliant) tokens.
- The team must also be careful not to add the same token twice for staking.
- Pending rewards are automatically distributed to users upon each deposit or withdraw.
- An emergency withdraw function is present, allowing users to withdraw their tokens in case of an issue, but that user's rewards will be forfeited.
- The team has the ability to withdraw any amount of $GGG from the contract address balance.
- As the contract is implemented with Solidity v0.8.x, it is protected from overflows/underflows.
Audit Findings Summary:
- Owners of fee-on-transfer tokens that will be used for staking will have the ability to exploit the contract.
- Please ensure trust in the team as they have substantial control in the ecosystem and can set fees up to 100%.
- Further ensure trust as the owner can withdraw any amount of $GGG from the contract address.
- Date: November 29th, 2021
Combined External Threat Results
|Arbitrary Storage Write||N/A||PASS|
|Centralization of Control||The team can withdraw any amount of $GGG from the contract address and set fees up to 100%.||WARNING|
|Delegate Call to Untrusted Contract||N/A||PASS|
|Dependence on Predictable Variables||The team depends on fees for any fee-on-transfer token to be static and predictable; but that is not necessarily the case.||WARNING|
|State Change External Calls||N/A||PASS|
|User Supplied Assertion||N/A||PASS|
|Critical Solidity Compiler||N/A||PASS|
|Overall Contract Safety||WARNING|
Details: MasterChef Staking
($) = 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] _transferOwnership # + ReentrancyGuard - [Pub] # + [Int] IERC20 - [Ext] totalSupply - [Ext] balanceOf - [Ext] transfer # - [Ext] allowance - [Ext] approve # - [Ext] transferFrom # + [Lib] Address - [Int] isContract - [Int] sendValue # - [Int] functionCall # - [Int] functionCall # - [Int] functionCallWithValue # - [Int] functionCallWithValue # - [Int] functionStaticCall - [Int] functionStaticCall - [Int] functionDelegateCall # - [Int] functionDelegateCall # - [Int] verifyCallResult + [Lib] SafeERC20 - [Int] safeTransfer # - [Int] safeTransferFrom # - [Int] safeApprove # - [Int] safeIncreaseAllowance # - [Int] safeDecreaseAllowance # - [Prv] _callOptionalReturn # + [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 + MasterChef (Ownable, ReentrancyGuard) - [Pub] # - [Pub] updateMultiplier # - modifiers: onlyOwner - [Ext] poolLength - [Pub] add # - modifiers: onlyOwner - [Pub] set # - modifiers: onlyOwner - [Pub] getMultiplier - [Ext] pendingRewards - [Pub] massUpdatePools # - [Pub] updatePool # - [Pub] deposit # - [Pub] withdraw # - [Pub] emergencyWithdraw # - [Ext] emergencyRewardWithdraw # - modifiers: onlyOwner - [Int] safeGggTransfer # - [Pub] dev #