Retro DeFi Native Strategy & Timelock Controller - Smart Contract Audit Report

Summary

TAO Audit Report Retro DeFi is building a yield aggregator on the Binance Smart Chain.

For this audit we reviewed the project's Native Strategy contract and Timelock Controller contract. We reviewed the contracts at commit 92accd6f9625328b5a0157de28ccdf84d792497e and again at commit 7d2870954b49263068af101d6afcd3c1b9250bba on GitHub. We also previously reviewed the project's Native Farm and Token contract here. Please note we have not reviewed the project's other strategy contracts.

Notes of the Contracts:
  • Users staking tokens into the projects farm will have their tokens forwarded to strategy contracts to earn yield on deposited assets when possible.
  • As this contract is for the project's native token, there is nowhere to earn yield. Users who deposit wil still earn rewards from farming, however.
  • There is a fee associated with making a deposit to the strategy, though this fee can only be set to a maximum of 0.5%. There is no way to claim fees in this contract, so the team should keep fees at 0%.
  • The TimelockController contract is intended to be the owner of the Strategy contract, delaying certian ownership-restricted actions.
  • For testing purposes, the delay is current 1 minute. Prior to deployment, we advise implementing a minimum of a 24-hour delay.
  • Users with large amounts of funds in the ecosystem should set up BSCscan alerts for this contract to monitor its activity.
  • The team can pause deposits into the strategy contracts and reblance them without any delay.
  • The team can also remove any tokens or BNB erroneously sent to either contract, though user's staked tokens cannot be moved.
  • The team has implement a series of recommendations around gas optimization.
  • Utilization of SafeMath to prevent overflow issues.
  • Audit Findings Summary:
    • No issues from external attackers were identified.
    • Ensure trust in the team as they have some control in the ecosyste.
    • Date: June 2nd, 2021.
    • Update Date: June 2nd, 2021.

    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: Native Strategy Contract


    ERC20 Token Graph

    Multi-file Token

    
    ($) = payable function
    # = non-constant function
    
    Int = Internal
    Ext = External
    Pub = Public
    
     +  Context 
        - [Int] _msgSender
        - [Int] _msgData
    
     + [Lib] SafeMath 
        - [Int] add
        - [Int] sub
        - [Int] sub
        - [Int] mul
        - [Int] div
        - [Int] div
        - [Int] mod
        - [Int] mod
    
     + [Int] IERC20 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     +  ERC20 (Context, IERC20)
        - [Pub]  #
        - [Pub] name
        - [Pub] symbol
        - [Pub] decimals
        - [Pub] totalSupply
        - [Pub] balanceOf
        - [Pub] transfer #
        - [Pub] allowance
        - [Pub] approve #
        - [Pub] transferFrom #
        - [Pub] increaseAllowance #
        - [Pub] decreaseAllowance #
        - [Int] _transfer #
        - [Int] _mint #
        - [Int] _burn #
        - [Int] _approve #
        - [Int] _setupDecimals #
        - [Int] _beforeTokenTransfer #
    
     + [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 #
    
     + [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
    
     +  Ownable (Context)
        - [Int]  #
        - [Pub] owner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
    
     + [Int] IPancakeswapFarm 
        - [Ext] poolLength
        - [Ext] userInfo
        - [Ext] getMultiplier
        - [Ext] pendingCake
        - [Ext] deposit #
        - [Ext] withdraw #
        - [Ext] enterStaking #
        - [Ext] leaveStaking #
        - [Ext] emergencyWithdraw #
    
     + [Int] IPancakeRouter01 
        - [Ext] factory
        - [Ext] WETH
        - [Ext] addLiquidity #
        - [Ext] addLiquidityETH ($)
        - [Ext] removeLiquidity #
        - [Ext] removeLiquidityETH #
        - [Ext] removeLiquidityWithPermit #
        - [Ext] removeLiquidityETHWithPermit #
        - [Ext] swapExactTokensForTokens #
        - [Ext] swapTokensForExactTokens #
        - [Ext] swapExactETHForTokens ($)
        - [Ext] swapTokensForExactETH #
        - [Ext] swapExactTokensForETH #
        - [Ext] swapETHForExactTokens ($)
        - [Ext] quote
        - [Ext] getAmountOut
        - [Ext] getAmountIn
        - [Ext] getAmountsOut
        - [Ext] getAmountsIn
    
     + [Int] IPancakeRouter02 (IPancakeRouter01)
        - [Ext] removeLiquidityETHSupportingFeeOnTransferTokens #
        - [Ext] removeLiquidityETHWithPermitSupportingFeeOnTransferTokens #
        - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
        - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($)
        - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #
    
     +  ReentrancyGuard 
        - [Int]  #
    
     +  Pausable (Context)
        - [Int]  #
        - [Pub] paused
        - [Int] _pause #
           - modifiers: whenNotPaused
        - [Int] _unpause #
           - modifiers: whenPaused
    
     +  StrategyNative (Ownable, ReentrancyGuard, Pausable)
        - [Pub]  #
        - [Pub] deposit #
           - modifiers: onlyOwner,whenNotPaused
        - [Pub] farm #
           - modifiers: nonReentrant
        - [Int] _farm #
        - [Pub] withdraw #
           - modifiers: onlyOwner,nonReentrant
        - [Pub] earn #
           - modifiers: whenNotPaused
        - [Int] buyBack #
        - [Int] distributeFees #
        - [Pub] convertDustToEarned #
           - modifiers: whenNotPaused
        - [Pub] pause #
        - [Ext] unpause #
        - [Pub] setEntranceFeeFactor #
        - [Pub] setControllerFee #
        - [Pub] setbuyBackRate #
        - [Pub] setGov #
        - [Pub] setOnlyGov #
        - [Pub] inCaseTokensGetStuck #
    


    Details: Timelock Controller Contract


    ERC20 Token Graph

    Multi-file Token

    
    ($) = 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 #
    
     + [Lib] SafeMath 
        - [Int] add
        - [Int] sub
        - [Int] sub
        - [Int] mul
        - [Int] div
        - [Int] div
        - [Int] mod
        - [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 #
    
     +  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
    
     +  AccessControl (Context)
        - [Pub] hasRole
        - [Pub] getRoleMemberCount
        - [Pub] getRoleMember
        - [Pub] getRoleAdmin
        - [Pub] grantRole #
        - [Pub] revokeRole #
        - [Pub] renounceRole #
        - [Int] _setupRole #
        - [Int] _setRoleAdmin #
        - [Prv] _grantRole #
        - [Prv] _revokeRole #
    
     +  ReentrancyGuard 
        - [Int]  #
    
     + [Int] INativeFarm 
        - [Ext] add #
        - [Ext] set #
    
     + [Int] IStrategy 
        - [Ext] earn #
        - [Ext] farm #
        - [Ext] pause #
        - [Ext] unpause #
        - [Ext] rebalance #
        - [Ext] deleverageOnce #
        - [Ext] wrapBNB #
        - [Ext] noTimeLockFunc1 #
        - [Ext] noTimeLockFunc2 #
        - [Ext] noTimeLockFunc3 #
    
     +  TimelockController (AccessControl, ReentrancyGuard)
        - [Pub]  #
        - [Ext]  ($)
        - [Pub] isOperationPending
        - [Pub] isOperationReady
        - [Pub] isOperationDone
        - [Pub] getTimestamp
        - [Pub] getMinDelay
        - [Pub] hashOperation
        - [Pub] hashOperationBatch
        - [Pub] schedule #
           - modifiers: onlyRole
        - [Pub] scheduleBatch #
           - modifiers: onlyRole
        - [Prv] _schedule #
        - [Pub] cancel #
           - modifiers: onlyRole
        - [Pub] execute ($)
           - modifiers: onlyRole,nonReentrant
        - [Pub] executeBatch ($)
           - modifiers: onlyRole,nonReentrant
        - [Prv] _beforeCall
        - [Prv] _afterCall #
        - [Prv] _call #
        - [Ext] updateMinDelay #
        - [Ext] updateMinDelayReduced #
        - [Pub] setDevWalletAddress #
        - [Pub] scheduleSet #
           - modifiers: onlyRole
        - [Pub] executeSet ($)
           - modifiers: onlyRole,nonReentrant
        - [Pub] withdrawBNB ($)
        - [Pub] withdrawBEP20 ($)
        - [Pub] add #
           - modifiers: onlyRole
        - [Pub] earn #
           - modifiers: onlyRole
        - [Pub] farm #
           - modifiers: onlyRole
        - [Pub] pause #
           - modifiers: onlyRole
        - [Pub] unpause #
           - modifiers: onlyRole
        - [Pub] rebalance #
           - modifiers: onlyRole
        - [Pub] deleverageOnce #
           - modifiers: onlyRole,nonReentrant
        - [Pub] wrapBNB #
           - modifiers: onlyRole
        - [Pub] noTimeLockFunc1 #
           - modifiers: onlyRole
        - [Pub] noTimeLockFunc2 #
           - modifiers: onlyRole
        - [Pub] noTimeLockFunc3 #
           - modifiers: onlyRole