FastSwap - Smart Contract Audit Report

FastSwap 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 CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of ControlThe team can withdraw $FAST tokens from the contract at any time.WARNING
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Deprecated OpcodesN/APASS
Ether ThiefN/APASS
External CallsN/APASS
Flash LoansN/APASS
Integer Over/UnderflowN/APASS
Multiple SendsN/APASS
State Change External CallsN/APASS
Unchecked RetvalN/APASS
User Supplied AssertionN/APASS
Critical Solidity CompilerN/APASS
Overall Contract Safety PASS

Function Graph

ERC20 Token Graph

Inheritance Chart

Multi-file Token

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 #