
EVCoin Presale and Staking - Smart Contract Audit Report
Audit Summary
Everest is building a new ERC-20 token sale platform as well as a staking contract for users to deposit tokens and earn yield in addition to claiming Everest NFTs.
For this audit, we reviewed the project team's EVCoinStaking and HellFirePresale contracts provided to us by the team.
We previously reviewed the project team's original $EVCoin token contract here.
Audit Findings
Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
Date: February 1st, 2022.Finding #1 - EVCoinStaking & HellFirePresale - Informational
Description: Several functions are declared public, but are never called internally. Several state variables can never be modified, but are not declared constant.Recommendation: We recommend declaring these functions external for additional gas savings on each call.- EVCoinStaking: stake, withdraw, harvest, onERC721Received, encodePackedData, withdrawETH - HellFirePresale: encodedPackedData, buyWithUSDT, claimToken, setSellStartDate, setSellEndDate, setClaimStartDate, setMaxMarketCap, setMinPerTransaction, setTokenPricePerUSDT, endSale, withdrawCollectedUSDT, withdrawCollectedAllUSDT, withdrawCollectedETH, withdrawUnsoldTokens
Resolution: The team has declared these functions external.Finding #2 - EVCoinStaking & HellFirePresale - Informational
Description: Several state variables can never be modified, but are not declared constant.Recommendation: We recommend declaring these state variables constant for additional gas savings on each call.- EVCoinStaking: EVTotalSupply - HellFirePresale: totalSold
Resolution: The EVTotalSupply variable is now set dynamically to the total supply of the staking token.
Contracts Overview
EVCoinStaking Contract:
- The contracts utilize ReentrancyGuard to prevent against re-entrancy attacks in applicable functions.
- As the contracts are implemented using Solidity v0.8.0, they are safe from any possible overflows/underflows.
HellFirePresale Contract:
- This contract allows users to stake a designated token into the contract in order to earn rewards in the form of a reward token determined by the project team until the total staked token limit in the contract is reached.
- Any Signer can claim a presale NFT one time, through the use of a signed message.
- Additionally, any Signer that also has tokens staked can claim one NFT at any time, through the use of a signed message.
- On deposits and withdrawals, any pending rewards are calculated and transferred to the user unless the total reward supply has been depleted.
- Reward amounts are calculated based on time staked, set reward rate, and total reward supply value.
- The project team should not use the reward token as a staking token or else rewards could be funded with users' staked funds.
- The user can trigger an emergency withdrawal, which will transfer all the user's deposited tokens to their wallet address, without calculating rewards.
- The owner is granted the Signer role upon deployment.
- The owner can grant or revoke the Signer role from any address at any time.
- Any user granted the Signer role can grant other addresses the Signer role at any time.
- The owner can withdraw any tokens or ETH from the contract at any time.
- The owner can change the reward rate at any time.
- The owner can set the reward token address at any time.
- The owner can set the staking limit to any value at any time.
- The owner can transfer ownership to another address at any time.
- The team must exercise caution when assigning the staking token to avoid using fee-on-transfer tokens.
- This contract allows eligible users to purchase a specified ERC-20 token, determined by the team, using a predefined price in USDT.
- Eligible users can purchase tokens through verification of a signed message while the sale is active until the maximum token amount has been reached. The purchase amount must be over the minimum transaction amount.
- Users can then claim portions of their purchased tokens once the sale period has ended and the claiming period has started.
- During the claiming period, users can claim 40% of their tokens within the first 14 days, 80% after 14 days, and 100% after 21 days.
- The owner can start/end the sale at any time.
- The owner can set the claiming period start date to any value, at any time.
- The owner can change the maximum token amount to any value at any time.
- The owner can set the token price in USDT to any value at any time.
- The owner can set the minimum transaction amount to any value at any time.
- The owner can withdraw any USDT tokens, presale tokens, or ETH stored in the contract at any time.
External Threat Results
| Vulnerability Category | Notes | Result |
|---|---|---|
| Arbitrary Storage Write | N/A | PASS |
| Arbitrary Jump | N/A | PASS | Centralization of Control | WARNING |
| Delegate Call to Untrusted Contract | N/A | PASS |
| Dependence on Predictable Variables | N/A | PASS |
| Deprecated Opcodes | N/A | PASS |
| Ether Thief | N/A | PASS |
| Exceptions | N/A | PASS |
| External Calls | N/A | PASS |
| Flash Loans | N/A | PASS |
| Integer Over/Underflow | N/A | PASS |
| Logical Issues | N/A | PASS |
| Multiple Sends | N/A | PASS |
| Oracles | N/A | PASS |
| Suicide | N/A | PASS |
| State Change External Calls | N/A | PASS |
| Unchecked Retval | N/A | PASS |
| User Supplied Assertion | N/A | PASS |
| Critical Solidity Compiler | N/A | PASS |
| Overall Contract Safety | PASS |
EVCoinStaking Contract


($) = payable function
# = non-constant function
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Int] IERC20Metadata (IERC20)
- [Ext] name
- [Ext] symbol
- [Ext] decimals
+ Context
- [Int] _msgSender
- [Int] _msgData
+ 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 #
+ ERC20Burnable (Context, ERC20)
- [Pub] burn #
- [Pub] burnFrom #
+ Pausable (Context)
- [Pub] #
- [Pub] paused
- [Int] _pause #
- modifiers: whenNotPaused
- [Int] _unpause #
- modifiers: whenPaused
+ ERC20Pausable (ERC20, Pausable)
- [Int] _beforeTokenTransfer #
+ [Int] IAccessControl
- [Ext] hasRole
- [Ext] getRoleAdmin
- [Ext] grantRole #
- [Ext] revokeRole #
- [Ext] renounceRole #
+ [Int] IAccessControlEnumerable (IAccessControl)
- [Ext] getRoleMember
- [Ext] getRoleMemberCount
+ [Lib] Strings
- [Int] toString
- [Int] toHexString
- [Int] toHexString
+ [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 #
+ [Lib] EnumerableSet
- [Prv] _add #
- [Prv] _remove #
- [Prv] _contains
- [Prv] _length
- [Prv] _at
- [Prv] _values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
+ AccessControlEnumerable (IAccessControlEnumerable, AccessControl)
- [Pub] supportsInterface
- [Pub] getRoleMember
- [Pub] getRoleMemberCount
- [Int] _grantRole #
- [Int] _revokeRole #
+ ERC20PresetMinterPauser (Context, AccessControlEnumerable, ERC20Burnable, ERC20Pausable)
- [Pub] #
- modifiers: ERC20
- [Pub] mint #
- [Pub] pause #
- [Pub] unpause #
- [Int] _beforeTokenTransfer #
+ Ownable (Context)
- [Pub] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Int] _transferOwnership #
+ ReentrancyGuard
- [Pub] #
+ [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] IERC721 (IERC165)
- [Ext] balanceOf
- [Ext] ownerOf
- [Ext] safeTransferFrom #
- [Ext] transferFrom #
- [Ext] approve #
- [Ext] getApproved
- [Ext] setApprovalForAll #
- [Ext] isApprovedForAll
- [Ext] safeTransferFrom #
+ [Int] IERC721Receiver
- [Ext] onERC721Received #
+ [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 #
+ [Lib] Roles
- [Int] add #
- [Int] remove #
- [Int] has
+ SignerRole (Context)
- [Pub] #
- [Pub] isSigner
- [Pub] addSigner #
- modifiers: onlySigner
- [Pub] renounceSigner #
- [Int] _addSigner #
- [Int] _removeSigner #
+ [Int] IMarketPlace721
- [Ext] mintBulkTokens #
+ EVCoinStaking (ReentrancyGuard, Pausable, Ownable, SignerRole, IERC721Receiver)
- [Pub] #
- [Ext] userStakeInfo
- [Ext] setRewardTokenAddress #
- modifiers: onlyOwner
- [Ext] setRewardPerWeek #
- modifiers: onlyOwner
- [Ext] setStakLimit #
- modifiers: onlyOwner
- [Pub] stake #
- modifiers: nonReentrant,whenNotPaused
- [Pub] withdraw #
- modifiers: nonReentrant
- [Ext] emergencyWithdraw #
- modifiers: nonReentrant
- [Ext] pendingReward
- [Int] _updatePool #
- [Pub] harvest #
- modifiers: nonReentrant
- [Pub] onERC721Received #
- [Pub] encodePackedData
- [Ext] claimPresaleNFT #
- [Ext] claimSatkeNFT #
- [Ext] addSignerRole #
- modifiers: onlyOwner
- [Ext] removeSignerRole #
- modifiers: onlyOwner
- [Int] toEthSignedMessageHash
- [Ext] recoverWrongTokens #
- modifiers: onlyOwner
- [Pub] withdrawETH #
- modifiers: onlyOwner
HellFirePresale Contract


($) = payable function
# = non-constant function
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Int] IERC20Metadata (IERC20)
- [Ext] name
- [Ext] symbol
- [Ext] decimals
+ Context
- [Int] _msgSender
- [Int] _msgData
+ 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 #
+ ERC20Burnable (Context, ERC20)
- [Pub] burn #
- [Pub] burnFrom #
+ Pausable (Context)
- [Pub] #
- [Pub] paused
- [Int] _pause #
- modifiers: whenNotPaused
- [Int] _unpause #
- modifiers: whenPaused
+ ERC20Pausable (ERC20, Pausable)
- [Int] _beforeTokenTransfer #
+ [Int] IAccessControl
- [Ext] hasRole
- [Ext] getRoleAdmin
- [Ext] grantRole #
- [Ext] revokeRole #
- [Ext] renounceRole #
+ [Int] IAccessControlEnumerable (IAccessControl)
- [Ext] getRoleMember
- [Ext] getRoleMemberCount
+ [Lib] Strings
- [Int] toString
- [Int] toHexString
- [Int] toHexString
+ [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 #
+ [Lib] EnumerableSet
- [Prv] _add #
- [Prv] _remove #
- [Prv] _contains
- [Prv] _length
- [Prv] _at
- [Prv] _values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
+ AccessControlEnumerable (IAccessControlEnumerable, AccessControl)
- [Pub] supportsInterface
- [Pub] getRoleMember
- [Pub] getRoleMemberCount
- [Int] _grantRole #
- [Int] _revokeRole #
+ ERC20PresetMinterPauser (Context, AccessControlEnumerable, ERC20Burnable, ERC20Pausable)
- [Pub] #
- modifiers: ERC20
- [Pub] mint #
- [Pub] pause #
- [Pub] unpause #
- [Int] _beforeTokenTransfer #
+ Ownable (Context)
- [Pub] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Int] _transferOwnership #
+ ReentrancyGuard
- [Pub] #
+ [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 #
- [Int] verifyCallResult
+ [Lib] SafeERC20
- [Int] safeTransfer #
- [Int] safeTransferFrom #
- [Int] safeApprove #
- [Int] safeIncreaseAllowance #
- [Int] safeDecreaseAllowance #
- [Prv] _callOptionalReturn #
+ [Lib] Roles
- [Int] add #
- [Int] remove #
- [Int] has
+ SignerRole (Context)
- [Pub] #
- [Pub] isSigner
- [Pub] addSigner #
- modifiers: onlySigner
- [Pub] renounceSigner #
- [Int] _addSigner #
- [Int] _removeSigner #
+ HellFirePresale (ReentrancyGuard, Pausable, Ownable, SignerRole)
- [Pub] #
- [Pub] encodePackedData
- [Int] toEthSignedMessageHash
- [Pub] buyWithUSDT ($)
- modifiers: checkSaleRequirements,nonReentrant
- [Pub] claimToken #
- modifiers: nonReentrant
- [Pub] setSellStartDate #
- modifiers: onlyOwner
- [Pub] setSellEndDate #
- modifiers: onlyOwner
- [Pub] setClaimStartDate #
- modifiers: onlyOwner
- [Pub] setMaxMarketCap #
- modifiers: onlyOwner
- [Pub] setMinPerTransaction #
- modifiers: onlyOwner
- [Pub] setTokenPricePerUSDT #
- modifiers: onlyOwner
- [Pub] endSale #
- modifiers: onlyOwner
- [Pub] withdrawCollectedUSDT #
- modifiers: onlyOwner
- [Pub] withdrawCollectedAllUSDT #
- modifiers: onlyOwner
- [Pub] withdrawCollectedETH #
- modifiers: onlyOwner
- [Pub] withdrawUnsoldTokens #
- modifiers: onlyOwner
- [Pub] unsoldTokens
- [Pub] calculateUSDTAmount