Liquid Driver - Smart Contract Audit Report
Summary
Liquid Driver has built an on-chain yield farming protocol.
For this audit, we analyzed the project's MasterChefV2 contract at 0xBfe3B559367ac4F0A80000FE7D83959b578C7bA0 and the project's StrategySpiritLqdrSpirit contract at 0x843e20b809c749858914044649210da7a9701efd on the Fantom mainnet.
Notes of the Contract:Audit Findings:
- Users can stake various LP tokens into the MasterChef contract into order to earn rewards.
- There is a fee associated with making a deposit into the contract on a pool-by-pool basis. Fees shall be sent to the project team.
- Users' rewards will automatically be claimed when they withdraw from the contract.
- Alternatively, users may claim just their rewards.
- In case of an issue or rewards running out, an emergencyWithdraw function is present; allowing users to withdraw while ignoring their rewards.
- Anyone can call harvestFromMasterChef() to bring rewards from the MasterChef V1 contract into this V2 contract. Please note we have not reviewed the MasterChef V1 contract.
- The project team can add different types of tokens for staking, and can update the reward rates for each token at any time.
- A Migrator function is present, allowing the team to migrate all of user's staked funds to a new contract without restriction.
- The team must exercise caution when adding tokens for staking to avoid fee-on-transfer and ERC-777 compliant tokens.
- Note that rewards are held in a separate contract not reviewed by our team.
- Some gas optimizations can be achieved through marking functions external instead of public and declaring some variables constant. As these contracts are already deployed, this is informational.
- The team must exercise caution when adding tokens for staking to avoid fee-on-transfer and ERC777-compliant tokens.
- Utilization of SafeMath (or similarily safe functions) across all contracts to prevent overflows.
- No security vulnerabilities from external actors were identified.
- Ensure trust in the team as they have the ability to migrate user's staked funds.
- Date: August 17th, 2021
External Threat Results
Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | N/A | PASS |
Delegate Call to Untrusted Contract | N/A | PASS |
Dependence on Predictable Variables | N/A | PASS |
Deprecated Opcodes | N/A | PASS |
Economic Issues | N/A | PASS |
Ether Thief | N/A | PASS |
Exceptions | N/A | PASS |
External Calls | N/A | PASS |
Integer Over/Underflow | N/A | PASS |
Multiple Sends | 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 |
Details: MasterChefV2
Function Graph
Inheritence Chart
Functions Overview
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] allowance
- [Ext] approve #
- [Ext] permit #
+ [Lib] BoringERC20
- [Int] safeSymbol
- [Int] safeName
- [Int] safeDecimals
- [Int] safeTransfer #
- [Int] safeTransferFrom #
+ [Int] IStrategy
- [Ext] rewards
- [Ext] gauge
- [Ext] want
- [Ext] timelock
- [Ext] deposit #
- [Ext] withdrawForSwap #
- [Ext] withdraw #
- [Ext] withdraw #
- [Ext] skim #
- [Ext] withdrawAll #
- [Ext] balanceOf
- [Ext] balanceOfWant
- [Ext] getHarvestable
- [Ext] harvest #
- [Ext] setTimelock #
- [Ext] setController #
- [Ext] execute ($)
- [Ext] execute ($)
+ [Int] ILiquidDepositor
- [Ext] setMiniChefAddress #
- [Ext] deposit #
- [Ext] withdraw #
- [Ext] withdrawAllToMiniChef #
- [Ext] balanceOf
+ [Int] IMasterChef
- [Ext] poolInfo
- [Ext] totalAllocPoint
- [Ext] deposit #
+ [Int] IRewarder
- [Ext] onLqdrReward #
- [Ext] pendingTokens
+ [Lib] SignedSafeMath
- [Int] mul
- [Int] div
- [Int] sub
- [Int] add
- [Int] toUInt256
+ [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
+ BoringOwnableData
+ BoringOwnable (BoringOwnableData)
- [Pub] #
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Pub] claimOwnership #
+ BaseBoringBatchable
- [Int] _getRevertMsg
- [Ext] batch ($)
+ BoringBatchable (BaseBoringBatchable)
- [Pub] permitToken #
+ [Lib] BoringMath
- [Int] add
- [Int] sub
- [Int] mul
- [Int] to128
- [Int] to64
- [Int] to32
+ [Lib] BoringMath128
- [Int] add
- [Int] sub
+ [Lib] BoringMath64
- [Int] add
- [Int] sub
+ [Lib] BoringMath32
- [Int] add
- [Int] sub
+ [Int] IMigratorChef
- [Ext] migrate #
+ MasterChefV2 (BoringOwnable, BoringBatchable)
- [Pub] #
- [Ext] setMasterChef #
- modifiers: onlyOwner
- [Pub] setFeeAddress #
- [Ext] init #
- [Pub] poolLength
- [Pub] add #
- modifiers: onlyOwner
- [Pub] set #
- modifiers: onlyOwner
- [Pub] setMigrator #
- modifiers: onlyOwner
- [Pub] migrate #
- [Ext] pendingLqdr
- [Ext] massUpdatePools #
- [Pub] lqdrPerBlock
- [Pub] updatePool #
- [Pub] deposit #
- [Int] _withdraw #
- [Pub] withdraw #
- [Pub] harvest #
- [Pub] withdrawAndHarvest #
- [Pub] harvestFromMasterChef #
- [Pub] emergencyWithdraw #
Details: StrategySpiritLqdrSpirit
Function Graph
Inheritence 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
+ [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 #
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Int] IMasterChef
- [Ext] BONUS_MULTIPLIER
- [Ext] add #
- [Ext] bonusEndBlock
- [Ext] deposit #
- [Ext] dev #
- [Ext] devFundDivRate
- [Ext] devaddr
- [Ext] emergencyWithdraw #
- [Ext] getMultiplier
- [Ext] massUpdatePools #
- [Ext] owner
- [Ext] pendingPickle
- [Ext] pendingReward
- [Ext] pending
- [Ext] pickle
- [Ext] picklePerBlock
- [Ext] poolInfo
- [Ext] poolLength
- [Ext] renounceOwnership #
- [Ext] set #
- [Ext] setBonusEndBlock #
- [Ext] setDevFundDivRate #
- [Ext] setPicklePerBlock #
- [Ext] startBlock
- [Ext] totalAllocPoint
- [Ext] transferOwnership #
- [Ext] updatePool #
- [Ext] userInfo
- [Ext] withdraw #
+ StrategyBase
- [Pub] #
- [Pub] balanceOfWant
- [Pub] balanceOfPool
- [Pub] balanceOf
- [Ext] whitelistHarvesters #
- [Ext] revokeHarvesters #
- [Ext] setGovernance #
- [Ext] setDepositor #
- [Pub] deposit #
- [Ext] withdraw #
- modifiers: onlyBenevolent
- [Ext] withdraw #
- [Ext] withdrawAll #
- [Int] _withdrawAll #
- [Int] _withdrawSome #
- [Pub] harvest #
+ [Int] ISpiritMasterChef
- [Ext] pendingSpirit
+ StrategyGeneralMasterChefBase (StrategyBase)
- [Pub] #
- modifiers: StrategyBase
- [Pub] balanceOfPool
- [Ext] getHarvestable
- [Pub] deposit #
- [Int] _withdrawSome #
- [Pub] harvest #
- modifiers: onlyBenevolent
+ StrategySpiritLqdrSpirit (StrategyGeneralMasterChefBase)
- [Pub] #
- modifiers: StrategyGeneralMasterChefBase
- [Ext] getHarvestable