FastSwap - Smart Contract Audit Report
FastSwap is building a new MasterChef staking contract for users to deposit assets and earn yield.
We reviewed the FastSwap MasterChef contract that is deployed at 0x4c3322Fb7Cd63987d62a99CB6FBd42F3FCb4eee8 on the Binance Smart Chain Mainnet.
Notes on the Contract:
- This contract allows anyone to stake a variety of assets determined by the team in order to earn rewards in the form of FastSwap tokens.
- Users will receive a reward amount on each block based on the amount staked; staking rewards can be calculated and transferred to the user at any time.
- On deposits and withdrawals, pending rewards are calculated and transferred to the user.
- On withdrawals, the user will receive the desired amount of the staking tokens; this amount cannot be more than the amount the user has deposited.
- The user can also trigger an emergency withdraw, which will transfer all the user's deposited LP tokens to their wallet address and set their balance and rewards to zero.
- The owner is able to add any token to be used as a staking token in the contract.
- The team must exercise caution when deciding the staking tokens to avoid fee-on-transfer and ERC777-compliant tokens (this is uncommon). The team should also not add the same token twice.
- The team should not add a staking pool for the $FAST reward token itself.
- The owner is able to withdraw the reward tokens from the contract at any time.
- The owner is able to set the start time and end time for rewards at any time.
- The owner can change the amount of rewards allocated to each pool.
- The owner can also change the duration of reward period at any time.
- The owner can change the amount of rewards allocated to each pool as well as the duration of reward period. Both of these factors can change the amount of rewards allocated.
- This contract contains multiplication on the result of a division in the pendingFast and updatePool functions. This can lead to slightly less accurate results.
- The following functions should be declared external instead of public to save a small amount of gas on each call: changeStartTime, changeEndTime, changeReward, changeDuration, add, deposit, withdraw, emergencyWithdraw, emergencyFastWithdraw.
Audit Findings Summary
- No external threats were identified.
- Ensure trust in the team as they have notable control in the ecosystem.
- Date: December 14th, 2021
- Updated March 8th, 2022 to reflect the contract's mainnet address.
Audit Results
Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | N/A | PASS |
Centralization of Control | The team can withdraw $FAST tokens from the contract at any time. | WARNING |
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 |
Flash Loans | N/A | PASS |
Integer Over/Underflow | N/A | PASS |
Multiple Sends | N/A | PASS |
Oracles | 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 |
Function Graph
Inheritance Chart
Functions Overview
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Int] functionDelegateCall #
- [Int] functionDelegateCall #
- [Prv] _verifyCallResult
+ Context
- [Int] _msgSender
- [Int] _msgData
+ [Lib] EnumerableSet
- [Prv] _add #
- [Prv] _remove #
- [Prv] _contains
- [Prv] _length
- [Prv] _at
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
+ [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] SafeERC20
- [Int] safeTransfer #
- [Int] safeTransferFrom #
- [Int] safeApprove #
- [Int] safeIncreaseAllowance #
- [Int] safeDecreaseAllowance #
- [Prv] _callOptionalReturn #
+ Ownable (Context)
- [Int] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
+ MasterChef (Ownable)
- [Pub] #
- [Pub] changeStartTime #
- modifiers: onlyOwner
- [Pub] changeEndTime #
- modifiers: onlyOwner
- [Pub] changeReward #
- modifiers: onlyOwner
- [Pub] changeDuration #
- modifiers: onlyOwner
- [Ext] poolLength
- [Ext] pendingFast
- [Pub] add #
- modifiers: onlyOwner
- [Pub] massUpdatePools #
- [Pub] updatePool #
- [Pub] deposit #
- [Pub] withdraw #
- [Pub] emergencyWithdraw #
- [Pub] emergencyFastWithdraw #
- modifiers: onlyOwner
- [Int] safeFastTransfer #