Strong INU Node - Smart Contract Audit Report

Summary

Strong Inu Node Audit Report Strong Inu is building a new platform where users can stake SINU tokens to earn rewards.

We reviewed the project team's Node contract using code provided to us by the project team.

We previously reviewed the project team's token contract here.

Notes on the Contract:
  • Any user may create a staking node by calling the createNode function, entering the number of nodes to be created and the name of the node(s). Names of nodes cannot be duplicated.
  • The total number of nodes assigned to an end user may not exceed a value set by the team (by default 100).
  • When creating nodes, the fee for each node will be transferred from the user to the contract. Fees are partially burned and partially sent to the team.
  • By default the fee is 0.001 ETH per node; though the fee can be updated by the team at any time.
  • Each node the user creates will be stored in the contract along with the timestamp when the next fee payment is due.
  • If multiple nodes are created in a single transaction, the creation time of the first node will be the current timestamp; while each subsequent node's creation timestamp will be incremented by 1 second.

  • Users who have created nodes must pay fees to maintain their nodes' good standing. Nodes that are not paid for will be disabled.
  • By default, fee payments are due every 30 days to the contract via the payNodeFee function.
  • Users can pay for each nodes created individually using the payNodeFee() function by specifying the creation time of the node to be paid for.
  • A payAllNodesFee function is also present, allowing users to pay fees on all nodes created by that user in a single transaction.
  • If a fee payment is not made on time, an "over duration" of 15 days applies; after which, if payment is not made, the node will no longer be eligible for rewards.
  • Nodes will earn rewards while they are not disabled. Users will earn rewards once per day, measured from the user's last claim time.
  • Users are able to claim their rewards at any time via the claimNodeReward() function or using claimAllNodesReward() function to claim rewards for all the user's nodes.

  • The owner can withdraw any $SINU (reward) tokens from the contract at any time.
  • The owner can also change the node price and reward per node per day at any time.
  • The fee percentages, fee amount, fee duration, and team wallet can be updated by the owner at any time.
  • The owner can set the over duration and the maximum number of nodes per user as well.

  • The burnAddress and feeDenomiator variables can be declared constant to save on deployment costs.
  • As the contract is implemented with Solidity v0.8.X, it is protected from any underflow/overflow attacks.
  • The contract also utilizes the SafeMath library to prevent overflows, which is redundant and could be removed to save on deployment costs if desired.

  • Resolved Issues:
    Issue: Two nodes can be assigned the same creation time for the same user, making one of the two nodes inaccessible for fee payments or reward collection.
    Scenario: If a user creates 20 nodes at 1640020000, that user's final node will be assigned the time of 1640020020. If the same user goes to create additional nodes in the next block (timestamp 1640020012), their first node will be assigned the already-used timestamp of 1640020012.
    Impact: Since the nodes will be out of order and two of the same creation time are present under a single user, the binary search operation will be unable to find a second node with the same creation time; making the user unable to pay to maintain that node or claim rewards.
    Fix: In the createNode() function, we advise implementing a require check to ensure that the user's last created node (if one exists) has a creation time which is less than the current timestamp.
    Validation: We have validated that the team has properly implemented this fix.

    Audit Findings Summary:
    • No security issues from outside attackers were identified.
    • Ensure trust in the team as they have notable control in the ecosystem.
    • Date: December 22nd, 2021.
    • Updated: December 23rd, 2021 to fix a minor potential issue.

    External Threat Results

    Vulnerability CategoryNotesResult
    Arbitrary Storage WriteN/APASS
    Arbitrary JumpN/APASS
    Centralization of Control
  • The owner can remove rewards from the contract.
  • The owner can set fees to any amount.
  • WARNING
    Delegate Call to Untrusted ContractN/APASS
    Dependence on Predictable VariablesN/APASS
    Deprecated OpcodesN/APASS
    Ether ThiefN/APASS
    ExceptionsN/APASS
    External CallsN/APASS
    Integer Over/UnderflowN/APASS
    Multiple SendsN/APASS
    SuicideN/APASS
    State Change External CallsN/APass
    Unchecked RetvalN/APASS
    User Supplied AssertionN/APASS
    Critical Solidity CompilerN/APASS
    Overall Contract Safety PASS

    DogeDash Farm Contract

    Smart Contract Graph

    Contract Inheritance

    
     ($) = payable function
     # = non-constant function
     
     Int = Internal
     Ext = External
     Pub = Public
     
     + [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] IBEP20 
        - [Ext] totalSupply
        - [Ext] decimals
        - [Ext] symbol
        - [Ext] name
        - [Ext] getOwner
        - [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 #
        - [Prv] _verifyCallResult
    
     + [Lib] SafeBEP20 
        - [Int] safeTransfer #
        - [Int] safeTransferFrom #
        - [Int] safeApprove #
        - [Int] safeIncreaseAllowance #
        - [Int] safeDecreaseAllowance #
        - [Prv] _callOptionalReturn #
    
     + [Int] ITokenReferral 
        - [Ext] recordReferral #
        - [Ext] recordReferralCommission #
        - [Ext] getReferrer
    
     +  Context 
        - [Int] _msgSender
        - [Int] _msgData
    
     +  Ownable (Context)
        - [Int]  #
        - [Pub] owner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
    
     +  ReentrancyGuard 
        - [Int]  #
    
     +  DogeDashFarm (Ownable, ReentrancyGuard)
        - [Pub]  #
        - [Ext] poolLength
        - [Pub] add #
           - modifiers: onlyOwner
        - [Pub] set #
           - modifiers: onlyOwner
        - [Pub] getMultiplier
        - [Ext] pendingToken
        - [Pub] canHarvest
        - [Pub] massUpdatePools #
        - [Pub] updatePool #
        - [Pub] deposit #
           - modifiers: nonReentrant
        - [Pub] withdraw #
           - modifiers: nonReentrant
        - [Pub] emergencyWithdraw #
           - modifiers: nonReentrant
        - [Int] payOrLockupPendingToken #
        - [Pub] setDevAddress #
        - [Pub] setFeeAddress #
        - [Pub] updateEmissionRate #
           - modifiers: onlyOwner
        - [Pub] setTokenReferral #
           - modifiers: onlyOwner
        - [Pub] setReferralCommissionRate #
           - modifiers: onlyOwner
        - [Int] payReferralCommission #
        - [Pub] addBalance #
           - modifiers: onlyOwner
        - [Int] mint #
        - [Int] safeTokenTransfer #
        - [Pub] getBlock

    Token Referral Contract

    Smart Contract Graph

    Contract Inheritance

    
     ($) = 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 #
    
     + [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] Address 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] functionDelegateCall #
        - [Int] functionDelegateCall #
        - [Prv] _verifyCallResult
    
     + [Lib] SafeBEP20 
        - [Int] safeTransfer #
        - [Int] safeTransferFrom #
        - [Int] safeApprove #
        - [Int] safeIncreaseAllowance #
        - [Int] safeDecreaseAllowance #
        - [Prv] _callOptionalReturn #
    
     + [Int] ITokenReferral 
        - [Ext] recordReferral #
        - [Ext] recordReferralCommission #
        - [Ext] getReferrer
    
     +  Context 
        - [Int] _msgSender
        - [Int] _msgData
    
     +  Ownable (Context)
        - [Int]  #
        - [Pub] owner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
    
     +  TokenReferral (ITokenReferral, Ownable)
        - [Pub] recordReferral #
           - modifiers: onlyOperator
        - [Pub] recordReferralCommission #
           - modifiers: onlyOperator
        - [Pub] getReferrer
        - [Ext] updateOperator #
           - modifiers: onlyOwner
        - [Ext] drainBEP20Token #
           - modifiers: onlyOwner

    Token Locker Contract

    Smart Contract Graph

    Contract Inheritance

    
     ($) = 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 #
    
     + [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] Address 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] functionDelegateCall #
        - [Int] functionDelegateCall #
        - [Prv] _verifyCallResult
    
     + [Lib] SafeBEP20 
        - [Int] safeTransfer #
        - [Int] safeTransferFrom #
        - [Int] safeApprove #
        - [Int] safeIncreaseAllowance #
        - [Int] safeDecreaseAllowance #
        - [Prv] _callOptionalReturn #
    
     +  Context 
        - [Int] _msgSender
        - [Int] _msgData
    
     +  Ownable (Context)
        - [Int]  #
        - [Pub] owner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
    
     +  TokenLocker (Ownable)
        - [Pub] unlock #
           - modifiers: onlyOwner

    TimeLock Contract

    Smart Contract Graph

    Contract Inheritance

    
     ($) = payable function
     # = non-constant function
     
     Int = Internal
     Ext = External
     Pub = Public
     
     + [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
    
     +  Timelock 
        - [Pub]  #
        - [Ext]  ($)
        - [Pub] setDelay #
        - [Pub] acceptAdmin #
        - [Pub] setPendingAdmin #
        - [Pub] queueTransaction #
        - [Pub] cancelTransaction #
        - [Pub] executeTransaction ($)
        - [Int] getBlockTimestamp