Smart Contract Audit Report
CasperPad 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 d01e76418398d2ad6e80435fe92a7973d5f04013 on the team's GitHub repository.
Please ensure trust in the team prior to investing as they have some control in the ecosystem.
Date: March 3rd, 2022.
Updated: March 9th, 2022 to address changes made by the team.
Finding #1 - MasterChef - Medium (Resolved)Description: The _rewardBalance variable is not appropriately deducted upon transferring rewards.
Risk/Impact: If there are not enough reward tokens in the contract for rewards, rewards will be funded with users' staked funds.
Recommendation: The project team should appropriately deduct from the reward balance when transferring harvested rewards so users are always able to withdraw their original staked amount.
Resolution: The team has implemented logic to correctly calculate rewards based on the reward token supply when harvesting rewards.
Finding #2 - MasterChef - InformationalDescription: Several functions are declared public, but are never called internally.Recommendation: We recommend declaring these functions external for additional gas savings on each call.
getPending, stake, unStake, harvest
- The contract allows users to stake tokens in order to earn rewards in the form of the same token until the reward tokens are depleted.
- On deposits, pending rewards are calculated and stored until the user withdraws their staked amount or harvests their rewards.
- When harvesting, users can choose to compound their calculated rewards into their staked token balance.
- Users' rewards are dependent on their amount staked and the contract's reward rate and time since rewards were last calculated.
- A harvest fee is deducted from the user's reward amount each time rewards are claimed.
- On withdrawals, rewards are calculated and transferred to the user. A fee amount is deducted from the withdrawal amount depending on the time staked. There are different fee amounts for stake times less than 7 days, between 7 and 14 days, between 14 and 21 days, between 21 and 30 days, and more than 30 days.
- The owner can transfer ownership at any time.
- The owner can update fee properties at any time.
- The owner can add and remove specific fees at any time.
- The owner can set the reward rate at any time.
- The owner can set the harvest fee amount to any value up to 40%.
- The owner can set the fee address at any time.
- The owner must use the depositReward() function to deposit reward tokens for them to be included in the _rewardBalance variable.
- As the contracts are implemented using Solidity v0.8.x, they are safe from any possible overflow/underflow attacks.
- The team must exercise caution when setting the staking/reward token and must avoid using any ERC-777 or fee-on-transfer 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.
|Arbitrary Jump/Storage Write||N/A||PASS|
|Centralization of Control||The team can set the unstaking fee up to 40%.||WARNING|
|Delegate Call to Untrusted Contract||N/A||PASS|
|Dependence on Predictable Variables||N/A||PASS|
|Improper Authorization Scheme||N/A||PASS|
|Outdated Compiler Version||N/A||PASS|
|Overall Contract Safety||PASS|
($) = payable function # = non-constant function Int = Internal Ext = External Pub = Public + [Int] IBEP20 - [Ext] totalSupply - [Ext] decimals - [Ext] symbol - [Ext] name - [Ext] getOwner - [Ext] balanceOf - [Ext] transfer # - [Ext] allowance - [Ext] approve # - [Ext] transferFrom # + Context - [Int] _msgSender - [Int] _msgData + 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 + [Lib] SafeBEP20 - [Int] safeTransfer # - [Int] safeTransferFrom # - [Int] safeApprove # - [Int] safeIncreaseAllowance # - [Int] safeDecreaseAllowance # - [Prv] _callOptionalReturn # + [Lib] Address - [Int] isContract - [Int] sendValue # - [Int] functionCall # - [Int] functionCall # - [Int] functionCallWithValue # - [Int] functionCallWithValue # - [Prv] _functionCallWithValue # + MasterChef (Ownable) - [Pub] # - [Prv] init # - [Ext] setFeeWallet # - modifiers: onlyOwner - [Ext] setUnStakeFee # - modifiers: onlyOwner - [Ext] addUnStakeFee # - modifiers: onlyOwner - [Ext] removeUnStakeFee # - modifiers: onlyOwner - [Ext] setHarvestFee # - modifiers: onlyOwner - [Pub] getMultiplier - [Pub] getPending - [Prv] _getPending - [Ext] getRewardBalance - [Ext] depositReward # - modifiers: onlyOwner - [Prv] updateStatus # - [Pub] stake # - [Pub] unStake # - [Pub] getUnStakeFeePercent - [Pub] harvest #
SourceHat (formerly Solidity Finance - founded in 2020) has quickly grown 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.