MCRT Staking

Smart Contract Audit Report

Audit Summary

MCRT Audit Report MCRTStaking is a new staking contract for users to deposit tokens and earn yield.

For this audit, we reviewed the project team's MCRTStaking contract at 0x50c50569c9706A9a3034AFefa954CECa78859853 on the Binance Smart Chain Mainnet.

Audit Findings

Please ensure trust in the team prior to investing as they have notable control in the ecosystem.
Date: April 13th, 2022.
Updated: April 18th, 2022, to reflect deployment to Binance Smart Chain Mainnet.

Contract Overview

  • This contract allows anyone to deposit a team-designated staking token in order to earn rewards in the form of more staking tokens or tokens from the Point contract address; the Point contract address is not provided in the scope of this audit, so we are unable to provide an assessment of the contract with regards to security.
  • On deposits, users set their staking entry's lock duration, token amount, and reward token option.
  • Users that choose not to receive Point tokens as rewards have a bonus token multiplier applied to their stake amount.
  • Users that choose to receive Point tokens as rewards must deposit at least the minimum stake amount for the corresponding lock duration set by the owner.
  • Users staking token rewards are calculated based on their staked token amount, the reward per token rate, and staking duration.
  • The reward per token rate is updated every time tokens are staked or unstaked and is based on the current reward rate, total tokens staked for staking token rewards, time since last update, and previous reward per token rate.
  • Users can withdraw their staked amount and claim staking token rewards once their staking entry's lock duration has elapsed unless the contract's reward token supply has been depleted.
  • If the contract's reward token supply is depleted, users staked and reward funds will be locked until more reward tokens are provided to the contract.
  • Users' Point token rewards are calculated based on their staking entry's total staking duration; Point token rewards can be claimed at any time.
  • Users that chose to receive Point tokens as rewards can unstake their staked tokens once the lock duration has elapsed.
  • The addTokenRewards() function must be used to deposit reward tokens or the funds will not be counted.
  • Anyone can deposit staking tokens to be used as rewards within the contract.
  • The owner can transfer ownership at any time.
  • The owner can change the owner address of the Point contract at any time.
  • The owner can change the reward rate to any value above 0 at any time.
  • The owner can set each staking duration's bonus multiplier to any value at any time.
  • The owner can toggle staking at any time.
  • The owner can set the minimum staking amount and Point token reward amount for each staking duration at any time.
  • The team must exercise caution when setting the staking/reward token and must avoid using any fee-on-transfer or ERC-777 tokens; if a fee-on-transfer token is used as the staking token then this contract should be excluded from the staking/reward token's fee mechanism.
  • As the contract is deployed with Solidity v0.8.x, it is protected from overflow/underflow attacks.

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Jump/Storage WriteN/APASS
Centralization of Control
  • The contract must have reward tokens for users to unstake and claim their staking tokens.
  • The owner can set the Point token reward rates to any values at any time.
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
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] IERC20Upgradeable 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

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

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

 +  Initializable 
    - [Prv] _isConstructor

 +  ContextUpgradeable (Initializable)
    - [Int] __Context_init #
       - modifiers: onlyInitializing
    - [Int] __Context_init_unchained #
       - modifiers: onlyInitializing
    - [Int] _msgSender
    - [Int] _msgData

 +  OwnableUpgradeable (Initializable, ContextUpgradeable)
    - [Int] __Ownable_init #
       - modifiers: onlyInitializing
    - [Int] __Ownable_init_unchained #
       - modifiers: onlyInitializing
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 + [Int] IPoints 
    - [Ext] totalPoints
    - [Ext] pointsOf
    - [Ext] transferPoints #
    - [Ext] allowancePoints
    - [Ext] approvePoints #
    - [Ext] transferFrom #
    - [Ext] mintPoints #
    - [Ext] burnPoints #
    - [Ext] transferOwnership #

 +  MCRTStaking (OwnableUpgradeable)
    - [Ext] initialize #
       - modifiers: initializer
    - [Pub] rewardPerToken
    - [Pub] earned
    - [Ext] stake #
       - modifiers: updateReward
    - [Ext] unstake #
       - modifiers: updateReward
    - [Ext] batchUnstake #
       - modifiers: updateReward
    - [Ext] getPointReward #
    - [Ext] batchGetPointReward #
    - [Int] getRewardInternal #
    - [Int] getPointInternal #
    - [Ext] setBonusMultiplier #
       - modifiers: onlyOwner
    - [Ext] setPointReward #
       - modifiers: onlyOwner
    - [Ext] setMinStakeTokensForPoint #
       - modifiers: onlyOwner
    - [Ext] setStakingEnabled #
       - modifiers: onlyOwner
    - [Ext] setRewardRate #
       - modifiers: onlyOwner
    - [Ext] transferPointOwnership #
       - modifiers: onlyOwner
    - [Ext] addTokenRewards #
    - [Pub] getAllAddressStakes

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 occurring 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.