Monopoli MasterChef

Smart Contract Audit Report

Audit Summary

Monopoli is building a new staking contract for users to deposit tokens and earn yield.

For this audit, we reviewed the project team's MasterChef contract at commit c32e2a65c1587da493f0eca95aa93cc84a5f7ae1 on the team's GitHub repository.

Audit Findings

Please ensure trust in the team prior to investing as they have some control in the ecosystem.
Date: March 9th, 2022.

Finding #1 - MasterChef - Informational

Description: Several functions are declared public, but are never called internally.
Masterchef.add, Masterchef.set, Masterchef.emergencyWithdraw, Masterchef.inCaseTokensGetStuck, Masterchef.setDevAddress, Masterchef.setFeeAddress, Masterchef.setEarningsReferral, Masterchef.setReferralCommissionRate, Masterchef.transferEarningTokenOwnership
Recommendation: We recommend declaring these functions external for additional gas savings on each call.

Finding #2 - MasterChef - Informational

Description: The MAX_WITHDRAWAL_FEE_BP variable is not used.
Recommendation: We recommend removing the MAX_WITHDRAWAL_FEE_BP variable to reduce contract size and save on deployment costs if they are not needed for future functionality.

Contract Overview

  • The MasterChef contract allows users to stake tokens in order to earn rewards in the form of a designated reward token.
  • Users' staked funds are deposited in and withdrawn from a designated strategy contact. The strategy contract is not in the scope of this audit, so we are unable to provide an assessment of the contract with regards to security.
  • On deposits and withdrawals, pending rewards are calculated and transferred to the user as long as the harvesting lock interval time has elapsed; the team must exercise caution as the harvesting lock interval is set on deployment and cannot be changed.
  • A deposit fee of up to 4% can be deducted from users' depositing amount; the deposit fee is transferred to the fee address.
  • Users can specify a referral address to receive reward tokens on deposits if there is an "Earning Referral" address and referral commission rate set; the amount of reward tokens the referral address receives is dependent on the referral commission rate. The "Earning Referral" contract is not in the scope of this audit, so we are unable to provide an assessment of the contract with regards to security.
  • Users' rewards are dependent on their amount staked and the pool's reward per share amount.
  • The reward per share amount is calculated using the contract's reward per second rate and the pool's allocation point percentage.
  • Each time rewards are calculated, the required amount of reward tokens are minted to the contract; additionally, the developer address is minted 10% of the calculated reward amount.
  • The user can also trigger an emergency withdrawal, which will transfer all the user's deposited tokens to their wallet address, without calculating rewards.

  • The owner can transfer ownership at any time.
  • The owner can change the start time until the contract's start time has been reached.
  • The owner can change the contract's end time to any time in the future.
  • The owner can add new staking pools at any time.
  • The owner can change all pools' allocation points and deposit fee at any time.
  • The owner can change the reward per second rate and subsequently the developer's reward rate at any time.
  • The owner can set the referral commission rate up to 50% at any time.
  • The owner can change the "Earnings Referral" address at any time.
  • The owner can update the fee and developer addresses at any time.
  • The owner can withdraw any tokens from the contract, except the reward token, at any time.
  • The team should be careful not to add the same token twice.
  • The team should be careful not to add the reward token as a staking token.
  • ReentrancyGuard is used on applicable functions to prevent reentrancy issues.
  • As the contract is implemented using Solidity v0.8.x, it is safe from any possible overflow/underflow attacks.

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Jump/Storage WriteN/APASS
Centralization of ControlUsers' staked funds are held within a separate contract.WARNING
Compiler IssuesN/APASS
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Ether/Token TheftN/APASS
Flash LoansN/APASS
Front RunningN/APASS
Improper EventsN/APASS
Improper Authorization SchemeN/APASS
Integer Over/UnderflowN/APASS
Logical IssuesN/APASS
Oracle IssuesN/APASS
Outdated Compiler VersionN/APASS
Race ConditionsN/APASS
ReentrancyN/APASS
Signature IssuesN/APASS
Unbounded LoopsN/APASS
Unused CodeN/APASS
Overall Contract Safety PASS

Inheritance Chart

Smart Contract Audit - Inheritance

Function Graph

Smart Contract Audit - Graph

Functions Overview


 ($) = 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 #

 + [Int] IERC20Metadata (IERC20)
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals

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

 +  ERC20 (Context, IERC20, IERC20Metadata)
    - [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] _spendAllowance #
    - [Int] _beforeTokenTransfer #
    - [Int] _afterTokenTransfer #

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Int] verifyCallResult

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

 +  ReentrancyGuard 
    - [Pub]  #

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

 + [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

 + [Int] IStrategy 
    - [Ext] wantLockedTotal
    - [Ext] earn #
    - [Ext] deposit #
    - [Ext] withdraw #

 + [Int] IEarningsReferral 
    - [Ext] recordReferral #
    - [Ext] recordReferralCommission #
    - [Ext] getReferrer
    - [Ext] updateOperator #

 +  MintableToken (ERC20)
    - [Ext] mint #

 +  Masterchef (Ownable, ReentrancyGuard)
    - [Ext] poolLength
    - [Pub]  #
    - [Pub] add #
       - modifiers: onlyOwner
    - [Pub] set #
       - modifiers: onlyOwner,poolExists
    - [Pub] getMultiplier
    - [Ext] pendingEarnings
    - [Pub] massUpdatePools #
    - [Pub] updatePool #
    - [Pub] deposit #
       - modifiers: nonReentrant,poolExists
    - [Pub] withdraw #
       - modifiers: nonReentrant,poolExists
    - [Pub] emergencyWithdraw #
       - modifiers: nonReentrant,poolExists
    - [Int] safeEarningsTransfer #
    - [Pub] inCaseTokensGetStuck #
       - modifiers: onlyOwner
    - [Pub] setDevAddress #
       - modifiers: onlyOwner
    - [Pub] setFeeAddress #
       - modifiers: onlyOwner
    - [Pub] setEarningsReferral #
       - modifiers: onlyOwner
    - [Pub] setReferralCommissionRate #
       - modifiers: onlyOwner
    - [Int] payReferralCommission #
    - [Pub] transferEarningTokenOwnership #
       - modifiers: onlyOwner
    - [Ext] setEarningsPerSecond #
       - modifiers: onlyOwner
    - [Ext] setStartTimestamp #
       - modifiers: onlyOwner
    - [Ext] setEndTimestamp #
       - modifiers: onlyOwner

About Solidity Finance

Solidity Finance was founded in 2020 and quickly grew to have one of the most experienced and well-equipped smart contract auditing teams in the industry. Our team has conducted 1000+ solidity smart contract audits covering all major project types and protocols, securing a total of over $50 billion U.S. dollars in on-chain value across 1500 projects!.
Our firm is well-reputed in the community and is trusted as a top smart contract auditing company for the review of solidity code, no matter how complex. Our team of experienced solidity smart contract auditors performs audits for tokens, NFTs, crowdsales, marketplaces, gambling games, financial protocols, and more!

Contact us today to get a free quote for a smart contract audit of your project!

What is a Solidity Audit?

Typically, a smart contract audit is a comprehensive review process designed to discover logical errors, security vulnerabilities, and optimization opportunities within code. A Solidity Audit takes this a step further by verifying economic logic to ensure the stability of smart contracts and highlighting privileged functionality to create a report that is easy to understand for developers and community members alike.

How Do I Interpret the Findings?

Each of our Findings will be labeled with a Severity level. We always recommend the team resolve High, Medium, and Low severity findings prior to deploying the code to the mainnet. Here is a breakdown on what each Severity level means for the project:

  • High severity indicates that the issue puts a large number of users' funds at risk and has a high probability of exploitation, or the smart contract contains serious logical issues which can prevent the code from operating as intended.
  • Medium severity issues are those which place at least some users' funds at risk and has a medium to high probability of exploitation.
  • Low severity issues have a relatively minor risk association; these issues have a low probability of occuring or may have a minimal impact.
  • Informational issues pose no immediate risk, but inform the project team of opportunities for gas optimizations and following smart contract security best practices.