Coinracer Staking - Smart Contract Audit Report

Summary

CoinracerStaking Audit Report Coinracer is building a new staking contract for users to deposit $CRACE and earn yield.

For this audit, we reviewed the project team's Staking contract at commit 5a711d8c019598669c4058d5ebf1f082b1c82fb7 on the team's GitHub repository.

We previously reviewed the project team's token, crowdsale, and vesting contracts here.

Notes on the Contract:
  • This contract allows anyone to stake $CRACE tokens in order to earn rewards in the form of more $CRACE tokens.
  • Each staking pool's APY and lock time values are set by the owner to calculate the rewards.
  • Users will receive a reward amount based on the amount staked, time in the pool, and APY of the staking pool.
  • Users can only claim the rewards when the staking pool lock time has elapsed.
  • Alternatively, users can choose to immediately re-invest their rewards back into the staking pool at any time.
  • Rewards are not withdrawn when the deposit amount is withdrawn.
  • Users can withdraw their staked tokens from a pool given that the pool is not locked.
  • The user can pay a withdrawal fee to trigger an emergency withdrawal, which will transfer all the user's deposited $CRACE tokens to their wallet address, forfeiting any owed rewards.
  • $CRACE tokens must be supplied to the contract to be distributed as rewards.
  • As the contract is implemented with Solidity v0.8.X, it is protected from any underflow/overflow attacks.
Ownership Controls:
  • The owner can add a staking pool at any time.
  • The owner can change the lock time, APY, and withdraw fee of any staking pool at any time.
  • The owner can transfer a specified amount of $CRACE token from the owner address to the contract address at any time.
  • The owner can withdraw the entire balance of the contract address and send it to a specified address at any time.

Audit Findings Summary:
  • It is possible for users to claim another user's tokens as rewards.
  • Ensure trust in the team as they have notable control in the ecosystem.
  • Date: December 17th, 2021.
  • Updated: December 20th, 2021 to address an issue with reward functions.
Resolved Issues
  • The team addressed an issue within the staking contract's reward functions in which if there was not enough $CRACE tokens in the contract for rewards, rewards would be funded with users' staked funds.

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of ControlThe owner can withdraw the entire balance of $CRACE tokens from the contract at any time.WARNING
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
Logical IssuesN/APASS
Multiple SendsN/APASS
OraclesN/APASS
SuicideN/APASS
State Change External CallsN/APASS
Unbounded LoopN/APASS
Unchecked RetvalN/APASS
User Supplied AssertionN/APASS
Critical Solidity CompilerN/APASS
Overall Contract Safety PASS

Function Graph

CoinRacerStaking


Inheritance Chart

CoinRacerStaking


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 #

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

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

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

 +  Staking (Ownable)
    - [Pub]  #
    - [Ext] poolLength
    - [Ext] fund #
       - modifiers: onlyOwner
    - [Ext] add #
       - modifiers: onlyOwner
    - [Ext] updatePool #
       - modifiers: onlyOwner
    - [Ext] deposited
    - [Ext] pending
    - [Ext] claimReward #
    - [Ext] compound #
    - [Ext] deposit #
    - [Ext] withdraw #
    - [Ext] emergencyWithdraw #
    - [Ext] withdrawFunds #
       - modifiers: onlyOwner