Matrix Farm - Smart Contract Audit Report

Summary

MatrixFarm Audit Report Matrix Farm is releasing a strategy contract to earn high yields for investors.

For this audit we reviewed Matrix Farm's Treasury, MatrixZap, MatrixVault, and MatrixLpAutoCompound contracts using code provided to us by the contract team.

Notes on the Matrix Vault Contract:
  • Users can stake a designated LP Token into the Matrix Vault, and will get back tokens that represent shares of rewards.
  • The Vault will then transfer the designated tokens to the Strategy contract.
  • This Strategy contract must be initially set within 20 minutes of the deployment of the MatrixVault contract.
  • Users are able to withdraw out of the Strategy contract through the Vault. This will send back the LP tokens, burning the Vault tokens in the process.
  • There is no fee associated with making a deposit into the Matrix Vault contract.
  • There is no fee associated with withdrawing from the Vault, but there is a fee of .1% for withdrawing from the Strategy contract. This fee is redistributed back amongst the shareholders.
  • The strategy can be changed by the owner. They must first propose the contract, which will have a publicly available address.
  • After waiting the designated delay period, the owner can then set the Strategy contract to the new strategy.
  • When a new strategy is set, all tokens will be withdrawn from the previous contract and deposited into the new one.
  • The owner is able to withdraw the total balance of any of the non-designated tokens in the Vault.
Notes on the MatrixLpAutoCompound Contract:
  • This contract serves as a valid Strategy contract for the MatrixVault contract.
  • All LP tokens deposited into this contract from the Matrix Vault are deposited into a MasterChef contract that is set upon deployment.
  • We did not review this MasterChef contract and did not verify the security as a part of this audit.
  • When rewards are harvested from the MasterChef contract, they are used to create more LP tokens. These are then deposited back into the MasterChef.
  • There are fees taken from the MasterChef rewards. The team takes a portion which is sent to their Treasury contract. The user who called the harvest function also gets a portion of the rewards as well.
  • The combined total of all fees cannot exceed 5%. The other fees are then calculated as a percent of the total fee.
  • The treasury fee defaults to 90% of the total fee upon deployment.
  • The call fee defaults to 10% of the total fee upon deployment.
  • The withdrawal fee defaults to .1% of the total fee upon deployment.
  • The owner is able to pause and unpause the contract at anytime.
  • Pausing the contract prevents deposits, and removes allowances from all the other contracts. Users can still withdraw when the contract is paused. Unpausing allows deposits and gives back the allowances.
  • The owner is also able to use the panic function. This will pause the deposits and subsequently withdraw all tokens from the MasterChef into this contract.
  • The owner can update the total fee up to the maximum of 5%.
  • The owner is able to adjust the fee given to the caller of the harvest function as well as the fee taken by the team.
  • The owner is able to swap any non-designated token in the contract for another token. The swapped token will be returned to the contract.
  • The owner is able to update the treasury where the team's fees are sent.
Notes on the MatrixZap contract:
  • This contract can be used to swap to and from the appropriate LP token for the vault.
  • Users can specify the address of the Matrix Vault they would like to deposit to, and the Matrix Zap will swap to the appropriate token and deposit into the vault for the user.
  • After depositing the user will receive back the Vault tokens to represent their share of rewards.
  • The user can also use this contract to withdraw from a specified vault and get a desired token back.
  • There are no fees associated with using the Matrix Zap contract.
  • There are no onlyOwner functions in this contract.
Notes on the Treasury contract:
  • This contract is where the team's fees are sent from the Strategy contract.
  • The owner is able to withdraw any ERC20 tokens and FTM from the Treasury.
  • The owner can designate an accountant address to mark transactions as "reviewed".

  • Utilization of SafeMath to prevent overflow issues and ReentrancyGuard to prevent reentrancy attacks.
Audit Findings Summary
  • No external threats were detected.
  • Ensure trust in the team as they have substantial control in the ecosystem.
  • Date: October 12th, 2021
  • Updated: October 13th, 2021 to address an issue with the makeCustomTxn function.
Resolved Issues
  • The team addressed an issue within the Strategy contract's makeCustomTxn function to reduce the amount of owner control.

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: MatrixVault Contract


MatrixVault Graph

MatrixVault


($) = payable function
# = non-constant function

  +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 + [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 #
    - [Prv] _functionCallWithValue #

 +  ERC20 (Context, IERC20)
    - [Pub] Constructor #
    - [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] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

 +  Ownable (Context)
    - [Int] Constructor #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner

 +  ReentrancyGuard 

 + [Int] IStrategy 
    - [Ext] vault
    - [Ext] want
    - [Ext] beforeDeposit #
    - [Ext] deposit #
    - [Ext] withdraw #
    - [Ext] balanceOf
    - [Ext] harvest #
    - [Ext] retireStrat #
    - [Ext] panic #
    - [Ext] pause #
    - [Ext] unpause #
    - [Ext] paused

 +  MatrixVault (ERC20, Ownable, ReentrancyGuard)
    - [Pub] Constructor #
       - modifiers: ERC20
    - [Pub] initialize #
       - modifiers: onlyOwner
    - [Pub] want
    - [Pub] balance
    - [Pub] available
    - [Pub] getPricePerFullShare
    - [Ext] depositAll #
    - [Pub] deposit #
       - modifiers: nonReentrant
    - [Pub] earn #
    - [Ext] withdrawAll #
    - [Pub] withdraw #
    - [Pub] proposeStrat #
       - modifiers: onlyOwner
    - [Pub] upgradeStrat #
       - modifiers: onlyOwner
    - [Ext] inCaseTokensGetStuck #
       - modifiers: onlyOwner


Details: MatrixLpAutoCompound Contract


MatrixLpAutoCompound Graph

MatrixLpAutoCompound


($) = payable function
# = non-constant function

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 +  Ownable (Context)
    - [Int] Constructor #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner

 + [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 #
    - [Prv] _functionCallWithValue #

 +  ERC20 (Context, IERC20)
    - [Pub] Constructor #
    - [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] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

 +  Pausable (Context)
    - [Int] Constructor #
    - [Pub] paused
    - [Int] _pause #
       - modifiers: whenNotPaused
    - [Int] _unpause #
       - modifiers: whenPaused

 + [Int] IUniswapRouterETH 
    - [Ext] addLiquidity #
    - [Ext] addLiquidityETH ($)
    - [Ext] removeLiquidity #
    - [Ext] removeLiquidityETH #
    - [Ext] swapExactTokensForTokens #
    - [Ext] swapExactETHForTokens ($)
    - [Ext] swapExactTokensForETH #
    - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #

 + [Int] IUniswapV2Pair 
    - [Ext] token0
    - [Ext] token1

 + [Int] IMasterChef 
    - [Ext] poolLength
    - [Ext] setBooPerSecond #
    - [Ext] getMultiplier
    - [Ext] pendingBOO
    - [Ext] massUpdatePools #
    - [Ext] updatePool #
    - [Ext] deposit #
    - [Ext] withdraw #
    - [Ext] userInfo
    - [Ext] emergencyWithdraw #

 +  MatrixLpAutoCompound (Ownable, Pausable)
    - [Pub] Constructor #
    - [Ext] beforeDeposit #
    - [Pub] deposit #
       - modifiers: whenNotPaused
    - [Ext] withdraw #
    - [Ext] harvest #
       - modifiers: whenNotPaused
    - [Int] chargeFees #
    - [Int] addLiquidity #
    - [Pub] balanceOf
    - [Pub] balanceOfWant
    - [Pub] balanceOfPool
    - [Ext] retireStrat #
    - [Pub] panic #
       - modifiers: onlyOwner
    - [Pub] pause #
       - modifiers: onlyOwner
    - [Ext] unpause #
       - modifiers: onlyOwner
    - [Int] _giveAllowances #
    - [Int] _removeAllowances #
    - [Ext] setWrappedRoute #
       - modifiers: onlyOwner
    - [Ext] makeCustomTxn #
       - modifiers: onlyOwner
    - [Int] approveTxnIfNeeded #
    - [Ext] updateTotalFee #
       - modifiers: onlyOwner
    - [Ext] updateCallFee #
       - modifiers: onlyOwner
    - [Ext] updateTreasury #
       - modifiers: onlyOwner



Details: MatrixZap Contract


MatrixZap Graph

MatrixZap


($) = payable function
# = non-constant function

 + [Int] IUniswapV2Pair 
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transfer #
    - [Ext] transferFrom #
    - [Ext] DOMAIN_SEPARATOR
    - [Ext] PERMIT_TYPEHASH
    - [Ext] nonces
    - [Ext] permit #
    - [Ext] MINIMUM_LIQUIDITY
    - [Ext] factory
    - [Ext] token0
    - [Ext] token1
    - [Ext] getReserves
    - [Ext] price0CumulativeLast
    - [Ext] price1CumulativeLast
    - [Ext] kLast
    - [Ext] mint #
    - [Ext] burn #
    - [Ext] swap #
    - [Ext] skim #
    - [Ext] sync #
    - [Ext] initialize #

 + [Lib] Babylonian 
    - [Int] sqrt

 + [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
    - [Prv] _verifyCallResult

 + [Lib] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

 + [Lib] LowGasSafeMath 
    - [Int] add
    - [Int] sub
    - [Int] mul
    - [Int] add
    - [Int] sub

 + [Int] IUniswapV2Router01 
    - [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] IUniswapV2Router02 (IUniswapV2Router01)
    - [Ext] removeLiquidityETHSupportingFeeOnTransferTokens #
    - [Ext] removeLiquidityETHWithPermitSupportingFeeOnTransferTokens #
    - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
    - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($)
    - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #

 + [Int] IWETH (IERC20)
    - [Ext] deposit ($)
    - [Ext] withdraw #

 + [Int] MatrixVault (IERC20)
    - [Ext] deposit #
    - [Ext] withdraw #

 +  MatrixZap 
    - [Pub] Constructor #
    - [Ext] Fallback ($)
    - [Ext] depositETH ($)
    - [Ext] depositNotInPair ($)
    - [Prv] _approveIfNeeded #
    - [Prv] _returnAssets #
    - [Prv] _removeLiquidity #
    - [Prv] _getSwapAmount
    - [Ext] withdraw #
    - [Prv] _swapTokensAndStake #


Details: Treasury Contract


Treasury Graph

Treasury


($) = payable function
# = non-constant function

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 +  Ownable (Context)
    - [Int] Constructor #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner

 + [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 #
    - [Prv] _functionCallWithValue #

 +  ERC20 (Context, IERC20)
    - [Pub] Constructor #
    - [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] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

 +  MatrixTreasury (Ownable)
    - [Pub] viewWithdrawal
    - [Pub] markReviewed #
    - [Ext] withdrawTokens #
       - modifiers: onlyOwner
    - [Ext] withdrawFTM #
       - modifiers: onlyOwner
    - [Pub] setAccountant #
       - modifiers: onlyOwner
    - [Ext] Fallback ($)