TAO Staking - Smart Contract Audit Report

Summary

TAO Audit Report The TAO team intends to build the first mintless and self-sustaining AMM yield aggregator on the Binance Smart Chain.


For this audit we reviewed the project's staking contract and xTAO token contract, deployed at the following addresses on the BSC Mainnet:
  • MasterChef Staking - 0xbf5d7f565101e62d2f7263a6a3a51b9635489139
  • xTAO Token - 0xa8c417708c9ba334c4701519942bf2b1ea9e49fb
  • Notes of the Token Contract:
    • The total supply of the token is set to 25 million.
    • No mint or burn functions are present; though the circulating supply can be reduced by sending tokens to the 0x..dead address, if desired.
    • Users who hold tokens will automatically receive a portion the fees from a transaction tax on each transfer.
    • Another portion of the fee charged on transactions will be sent to the staking contract to provide for rewards.
    • The owner can update the tax rates at any time; though only up to a maximum of 3%
    • The owner can also exclude and include accounts from the fee mechanism at any time.
    • Ownership has been transferred to a timelock contract. Users can monitor this contract to preview owner actions.
    • The team retaining ownership of the token does not pose a risk.
    • The team worked with us to implement some slight gas optimizations to this contract.
    • The contract utilizes SafeMath libraries to prevent overflows along with following the BEP20 standard.
      Notes of the MasterChef Staking Contract:
    • Users can stake various tokens into the MasterChef contract in order to earn xTAO tokens.
    • There is a fee associated with making a deposit to the contract, set by the team separately for each token.
    • The team must provide the reward tokens manually. The duration of the rewards period will be based on the number of tokens available in the contract and the emission rate which can be updated by the team.
    • There is a built-in buffer of 260 days for rewards, though the team can update this value at any time. View funcitons are implemented to check the theoretical time remaining for rewards.
    • The project team can add different types of tokens for staking, and can update the reward rates for each token.
    • Ownership has been transferred to a timelock contract. Users can monitor this contract to preview owner actions.
    • The team cannot remove any user-deposited assets from the contract.
    • The team worked with us to implement some slight gas optimizations to this contract.
    • Utilization of SafeMath (or similarily safe functions) to prevent overflow issues.
    Audit Findings Summary
    • No issues from external attackers were identified.
    • Ensure trust in the team as they have notable power over the staking contract.
    • Date: May 10th, 2021.
    • Update Date: May 17th, 2021 - Movement of ownership to a timelock contract.

    External Threat Results

    Vulnerability CategoryNotesResult
    Arbitrary Storage WriteN/APASS
    Arbitrary JumpN/APASS
    Delegate Call to Untrusted ContractN/APASS
    Dependence on Predictable VariablesN/APASS
    Deprecated OpcodesN/APASS
    Ether ThiefN/APASS
    ExceptionsN/APASS
    External CallsN/APASS
    Flash LoansN/APASS
    Integer Over/UnderflowN/APASS
    Multiple SendsN/APASS
    OraclesN/APASS
    SuicideN/APASS
    State Change External CallsN/APASS
    Unchecked RetvalN/APASS
    User Supplied AssertionN/APASS
    Critical Solidity CompilerN/APASS
    Overall Contract Safety PASS


    Details: xTAO


    ERC20 Token Graph

    Multi-file Token

    
     ($) = 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
        - [Prv] _verifyCallResult
    
     + [Lib] SafeMath 
        - [Int] add
        - [Int] sub
        - [Int] sub
        - [Int] mul
        - [Int] div
        - [Int] div
        - [Int] mod
        - [Int] mod
    
     + [Int] IBEP20 
        - [Ext] totalSupply
        - [Ext] decimals
        - [Ext] symbol
        - [Ext] name
        - [Ext] getOwner
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     +  Context 
        - [Int] _msgSender
        - [Int] _msgData
    
     +  Ownable (Context)
        - [Int]  #
        - [Pub] owner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
    
     +  xTAO (Context, IBEP20, Ownable)
        - [Pub]  #
        - [Ext] setTaxFeePercent #
           - modifiers: onlyOwner
        - [Ext] setStakingFeePercent #
           - modifiers: onlyOwner
        - [Ext] getOwner
        - [Pub] name
        - [Pub] symbol
        - [Pub] decimals
        - [Pub] totalSupply
        - [Pub] balanceOf
        - [Pub] transfer #
        - [Pub] allowance
        - [Pub] approve #
        - [Pub] transferFrom #
        - [Pub] increaseAllowance #
        - [Pub] decreaseAllowance #
        - [Pub] isExcluded
        - [Pub] totalFees
        - [Pub] reflect #
        - [Pub] reflectionFromToken
        - [Pub] tokenFromReflection
        - [Ext] excludeAccount #
           - modifiers: onlyOwner
        - [Ext] includeAccount #
           - modifiers: onlyOwner
        - [Prv] _approve #
        - [Prv] _transfer #
        - [Prv] _takeStaking #
        - [Prv] _transferStandard #
        - [Prv] _transferToExcluded #
        - [Prv] _transferFromExcluded #
        - [Prv] _transferBothExcluded #
        - [Prv] _reflectFee #
        - [Prv] calculateTaxFee
        - [Prv] calculateStakingFee
        - [Prv] _getValues
        - [Prv] _getTValues
        - [Prv] _getRValues
        - [Prv] _getRate
        - [Prv] _getCurrentSupply


    Details: MasterChef


    ERC20 Token Graph

    Multi-file Token

    
     ($) = payable function
     # = non-constant function
     
     Int = Internal
     Ext = External
     Pub = Public
    
     +  Context 
        - [Int] _msgSender
        - [Int] _msgData
    
     +  Ownable (Context)
        - [Int]  #
        - [Pub] owner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
    
     + [Lib] Address 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Prv] _verifyCallResult
    
     + [Lib] SafeBEP20 
        - [Int] safeTransfer #
        - [Int] safeTransferFrom #
        - [Int] safeApprove #
        - [Int] safeIncreaseAllowance #
        - [Int] safeDecreaseAllowance #
        - [Prv] _callOptionalReturn #
    
     + [Int] IBEP20 
        - [Ext] totalSupply
        - [Ext] decimals
        - [Ext] symbol
        - [Ext] name
        - [Ext] getOwner
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     + [Lib] SafeMath 
        - [Int] add
        - [Int] sub
        - [Int] sub
        - [Int] mul
        - [Int] div
        - [Int] div
        - [Int] mod
        - [Int] mod
    
     +  xTAO (Context, IBEP20, Ownable)
        - [Pub]  #
        - [Ext] setTaxFeePercent #
           - modifiers: onlyOwner
        - [Ext] setStakingFeePercent #
           - modifiers: onlyOwner
        - [Ext] getOwner
        - [Pub] name
        - [Pub] symbol
        - [Pub] decimals
        - [Pub] totalSupply
        - [Pub] balanceOf
        - [Pub] transfer #
        - [Pub] allowance
        - [Pub] approve #
        - [Pub] transferFrom #
        - [Pub] increaseAllowance #
        - [Pub] decreaseAllowance #
        - [Pub] isExcluded
        - [Pub] totalFees
        - [Pub] reflect #
        - [Pub] reflectionFromToken
        - [Pub] tokenFromReflection
        - [Ext] excludeAccount #
           - modifiers: onlyOwner
        - [Ext] includeAccount #
           - modifiers: onlyOwner
        - [Prv] _approve #
        - [Prv] _transfer #
        - [Prv] _takeStaking #
        - [Prv] _transferStandard #
        - [Prv] _transferToExcluded #
        - [Prv] _transferFromExcluded #
        - [Prv] _transferBothExcluded #
        - [Prv] _reflectFee #
        - [Prv] calculateTaxFee
        - [Prv] calculateStakingFee
        - [Prv] _getValues
        - [Prv] _getTValues
        - [Prv] _getRValues
        - [Prv] _getRate
        - [Prv] _getCurrentSupply
    
     +  MasterChef (Ownable)
        - [Pub]  #
        - [Ext] poolLength
        - [Pub] add #
           - modifiers: onlyOwner
        - [Pub] set #
           - modifiers: onlyOwner
        - [Pub] getMultiplier
        - [Ext] pendingTao
        - [Pub] massUpdatePools #
        - [Pub] updatePool #
        - [Pub] deposit #
        - [Pub] withdraw #
        - [Pub] emergencyWithdraw #
        - [Pub] dev #
        - [Ext] previewSelfSustainRate
        - [Pub] selfSustainRate #
           - modifiers: onlyOwner
        - [Pub] updateDaysInBuffer #
           - modifiers: onlyOwner
        - [Int] TaoTransfer #
        - [Pub] updateEmissionRate #
           - modifiers: onlyOwner