Assent Protocol

Smart Contract Audit Report

Audit Summary

Assent Protocol Audit Report Assent Protocol is creating a new token and staking contract.

For this audit, we reviewed Assent Protocol's contracts within the farming-contracts folder at commit 96bc9ed14b95879a1d767e21f5891bcf40d3e06c on the team's GitHub repository.

Audit Findings

Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
Date: March 14th, 2022.
Updated: March 15th, 2022 to reflect changes from commit 3a99254d58a37db69264f3afd26f89e08f83ea20 to commit 96bc9ed14b95879a1d767e21f5891bcf40d3e06c.

Finding #1 - AssentToken - High (Resolved)

Description: A public burn function exists which takes an address and an amount as parameters.
Risk/Impact: Any user can burn any other user's tokens at any time.
Recommendation: The team should either remove this function or update it to only allow users to burn their own tokens or tokens they have an approval for.
Resolution: The team has removed this function.

Finding #2 - ASNTToken, AssentReferral, & AssentMasterchef - Informational (Resolved)

Description: The following functions are declared public, but are never called internally:
ASNTToken.pause(), ASNTToken.unpause(), AssentReferral.recordReferral(), AssentReferral.recordReferralCommission(), 
AssentReferral.getReferrer(), AssentMasterchef.deposit(), AssentMasterchef.withdraw(), AssentMasterchef.emergencyWithdraw(), 
AssentMasterchef.harvestMany(), AssentMasterchef.add(), AssentMasterchef.set(), AssentMasterchef.updateAllocPoint(),
AssentMasterchef.updateEmissionRate(), AssentMasterchef.startFarmingNow(), AssentMasterchef.startFarmingAtTime(), 
AssentMasterchef.setASNTReferral(), AssentMasterchef.setReferralCommissionRate(), AssentMasterchef.setASNTShareAddress(), 
AssentMasterchef.setASNTSharePercent(), AssentMasterchef.setFeeAddress(), AssentMasterchef.setVIP().
Recommendation: These functions can be declared external for additional gas savings on each call.
Resolution: The team has declared these functions external.

Contracts Overview

  • As the contracts are implemented with Solidity v0.8.0, they are safe from any possible overflows/underflows.
ASNTToken Contract:
  • $ASNT is intended to be used as a reward token for the AssentMasterchef contract.
  • The maximum allowed supply of $ASNT is one hundred million tokens (100,000,000).
  • The contract's deployer is granted the Admin Role, Pauser Role, Minter Role, and Rescuer Role upon deployment.
  • The Minter Role has the ability to mint any amount of tokens to any address as long as it does not result in the total supply exceeding the maximum total supply.
  • Users can burn their own tokens to reduce the total supply, if desired.
  • The Rescuer Role has the ability to withdraw any tokens erroneously sent to this contract.
  • The Pauser Role has the ability to pause the contract at any time, disabling all minting, burning, and transfers.
  • The contract implements the EIP-2612 standard in order to support permits which allows for gasless approvals to be made via signatures.
  • The Admin Role can grant or remove any role from any address at any time.
AssentReferral Contract:
  • This contract facilitates the referral functionality in the AssentMasterchef contract.
  • Any "Operator" can set a user's referrer as long as their referrer has not been previously set.
  • The owner can add or remove any address from the list of Operators at any time.
AssentMasterchef Contract:
  • Any user may deposit specified tokens into staking pools to earn rewards in $ASNT and potentially other rewards from additional reward distributors.
  • Once the owner has enabled farming, users will receive a reward amount on each block based on the amount staked and the amount of points allocated to the pool.
  • Users may only claim their rewards once per "harvest" period. Each pool has its own harvest period and may vary between pools.
  • There is a deposit fee of up to 5% which is transferred to a Fee address controlled by the team. Each pool has its own deposit fee and may vary between pools.
  • This fee may be reduced for a user based on an associated AssentVIP contract.
  • As the AssentVIP contract was not included in the scope of this audit, we are unable to provide an assessment regarding functionality or security.
  • The maximum fee allowed fee reduction is 80%.
  • Additionally, a team fee is taken from distributed $ASNT rewards and transferred to an ASNTShare address controlled by the team.
  • If a user has not already specified a referrer, they can can set one when depositing. Referrals are stored in the associated ASNTReferral contract.
  • When a user earns rewards, their referrer will be minted an additional percentage of the reward amount based on the contract's referral rate.
  • When claiming, if a user has not waited until a pool's "harvest fee period" has passed since their last claim from the pool, they will have a harvest fee taken from their rewards.
  • Pending rewards are calculated and minted to the user on deposits or withdrawals, if eligible.
  • Rewards will not be minted if it results in the total supply of ASNT exceeding the maximum allowed supply.
  • The user can also trigger an emergency withdraw, which will transfer the user's deposited tokens from a pool to their wallet address, without calculating rewards.

  • The owner add a new pool at any time.
  • The owner can update a pool's allocation points at any time.
  • The owner can update a pool's reward rate at any time as long as it does not exceed 50 tokens per second.
  • The owner can update a pool's deposit fee, harvest period, harvest fee period, harvest fee percentage, and additional reward distributors for each pool at any time.
  • The maximum allowed harvest period and and maximum allowed harvest fee period are 5 days.
  • The maximum allowed harvest fee is 10%.
  • The number of additional reward distributors cannot exceed 10.
  • The owner can update the referral commission rate and ASNTShare percentage at any time.
  • The owner can update the fee address, ASNTReferral contract address, AssentVIP contract address, and ASNTShare address at any time.
  • ReentrancyGuard is utilized to prevent reentrancy attacks in applicable functions.

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Jump/Storage WriteN/APASS
Centralization of Control
  • The owner has the permissions described above.
  • The Minter Role can mint $ASNT to any address at any time.
  • The Pauser Role can disable all $ASNT minting and transfers at any time.
  • The owner can update a pool's attributes at any time.
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

AssentReferral Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function
 
  +  Context 
    - [Int] _msgSender
    - [Int] _msgData

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

 + [Int] IERC20 
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals
    - [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 #

 + [Int] IReferral 
    - [Ext] recordReferral #
    - [Ext] recordReferralCommission #
    - [Ext] getReferrer

 +  AssentReferral (IReferral, Ownable)
    - [Pub] recordReferral #
       - modifiers: onlyOperator
    - [Pub] recordReferralCommission #
       - modifiers: onlyOperator
    - [Pub] getReferrer
    - [Ext] updateOperator #
       - modifiers: onlyOwner

 

ASNTToken & AssentMasterChef Contracts

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function
 
  +  Context 
    - [Int] _msgSender
    - [Int] _msgData

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

 +  ReentrancyGuard 
    - [Pub]  #

 + [Int] IERC20 
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

 + [Int] IMultipleRewards 
    - [Ext] onASNTReward #
    - [Ext] pendingTokens
    - [Ext] rewardToken
    - [Ext] poolRewardsPerSec
    - [Ext] getPoolInfo

 + [Int] IReferral 
    - [Ext] recordReferral #
    - [Ext] recordReferralCommission #
    - [Ext] getReferrer

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

 + [Int] IERC20Permit 
    - [Ext] permit #
    - [Ext] nonces
    - [Ext] DOMAIN_SEPARATOR

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

 +  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] _beforeTokenTransfer #
    - [Int] _afterTokenTransfer #

 + [Lib] Strings 
    - [Int] toString
    - [Int] toHexString
    - [Int] toHexString

 + [Lib] ECDSA 
    - [Prv] _throwError
    - [Int] tryRecover
    - [Int] recover
    - [Int] tryRecover
    - [Int] recover
    - [Int] tryRecover
    - [Int] recover
    - [Int] toEthSignedMessageHash
    - [Int] toEthSignedMessageHash
    - [Int] toTypedDataHash

 +  EIP712 
    - [Pub]  #
    - [Int] _domainSeparatorV4
    - [Prv] _buildDomainSeparator
    - [Int] _hashTypedDataV4

 + [Lib] Counters 
    - [Int] current
    - [Int] increment #
    - [Int] decrement #
    - [Int] reset #

 +  ERC20Permit (ERC20, IERC20Permit, EIP712)
    - [Pub]  #
       - modifiers: EIP712
    - [Pub] permit #
    - [Pub] nonces
    - [Ext] DOMAIN_SEPARATOR
    - [Int] _useNonce #

 +  ERC20Burnable (Context, ERC20)
    - [Pub] burn #
    - [Pub] burnFrom #

 + [Int] IAccessControl 
    - [Ext] hasRole
    - [Ext] getRoleAdmin
    - [Ext] grantRole #
    - [Ext] revokeRole #
    - [Ext] renounceRole #

 + [Int] IERC165 
    - [Ext] supportsInterface

 +  ERC165 (IERC165)
    - [Pub] supportsInterface

 +  AccessControl (Context, IAccessControl, ERC165)
    - [Pub] supportsInterface
    - [Pub] hasRole
    - [Int] _checkRole
    - [Pub] getRoleAdmin
    - [Pub] grantRole #
       - modifiers: onlyRole
    - [Pub] revokeRole #
       - modifiers: onlyRole
    - [Pub] renounceRole #
    - [Int] _setupRole #
    - [Int] _setRoleAdmin #
    - [Int] _grantRole #
    - [Int] _revokeRole #

 +  Pausable (Context)
    - [Pub]  #
    - [Pub] paused
    - [Int] _pause #
       - modifiers: whenNotPaused
    - [Int] _unpause #
       - modifiers: whenPaused

 +  ASNTToken (ERC20Burnable, ERC20Permit, AccessControl, Pausable)
    - [Pub]  #
       - modifiers: ERC20,ERC20Permit
    - [Pub] mint #
       - modifiers: onlyRole
    - [Pub] burn #
    - [Ext] maxSupply
    - [Ext] rescueTokens #
       - modifiers: onlyRole
    - [Pub] pause #
       - modifiers: onlyRole
    - [Pub] unpause #
       - modifiers: onlyRole
    - [Int] _beforeTokenTransfer #
       - modifiers: whenNotPaused

 + [Int] IAssentVIP 
    - [Ext] isVIP
    - [Ext] getFarmsDepFeeReduction

 +  AssentMasterchef (Ownable, ReentrancyGuard)
    - [Pub]  #
    - [Ext] poolLength
    - [Ext] pendingTokens
       - modifiers: validatePoolByPid
    - [Ext] poolRewardsDatas
       - modifiers: validatePoolByPid
    - [Ext] poolRewarders
       - modifiers: validatePoolByPid
    - [Pub] canHarvest
       - modifiers: validatePoolByPid
    - [Pub] noHarvestFee
    - [Ext] poolTotalLp
    - [Pub] getUserDepositFee
    - [Pub] getFarmsDepFeeReduction
    - [Ext] massUpdatePools #
       - modifiers: nonReentrant
    - [Int] _massUpdatePools #
    - [Int] _checkBeforeMintRewards #
    - [Ext] updatePool #
       - modifiers: nonReentrant
    - [Int] _updatePool #
       - modifiers: validatePoolByPid
    - [Pub] deposit #
       - modifiers: nonReentrant
    - [Int] _deposit #
       - modifiers: validatePoolByPid
    - [Pub] withdraw #
       - modifiers: nonReentrant,validatePoolByPid
    - [Pub] emergencyWithdraw #
       - modifiers: nonReentrant
    - [Int] payOrLockupPendingASNT #
    - [Int] safeASNTTransfer #
    - [Pub] harvestMany #
       - modifiers: nonReentrant
    - [Int] payReferralCommission #
    - [Pub] add #
       - modifiers: onlyOwner
    - [Pub] set #
       - modifiers: onlyOwner,validatePoolByPid
    - [Pub] updateAllocPoint #
       - modifiers: onlyOwner
    - [Pub] updateEmissionRate #
       - modifiers: onlyOwner
    - [Pub] startFarmingNow #
       - modifiers: onlyOwner
    - [Pub] startFarmingAtTime #
       - modifiers: onlyOwner
    - [Pub] setASNTReferral #
       - modifiers: onlyOwner
    - [Pub] setReferralCommissionRate #
       - modifiers: onlyOwner
    - [Pub] setASNTShareAddress #
    - [Pub] setASNTSharePercent #
       - modifiers: onlyOwner
    - [Pub] setFeeAddress #
    - [Pub] setVIP #
       - 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 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.