Coinracer - Smart Contract Audit Report
Summary
Coinracer is releasing a new token, a crowdsale contract, and a vesting contract.
For this audit, we reviewed the following contracts:
- CoinracerToken contract at 0xFBb4F2f342c6DaaB63Ab85b0226716C4D1e26F36 on the Binance Smart Chain Mainnet.
- TokenVestingFactory contract at 0xe090601Fa5da23350EDB46C939b78A75960d9D74 on the Binance Smart Chain Mainnet.
- Crowdsale and TokenVesting contracts at commit 3c4ae6f85ed65aa6aad672794db17d820ac99f39 on the team's Github repository.
CoinracerToken Contract:Crowdsale Contract:
- The total supply of the token is set to 100 million $CRACE tokens.
- No mint or burn functions are present beyond deployment; though the circulating supply can be reduced by sending tokens to the 0x..dead address if desired.
- At the time of writing this report, 90.4% of the token supply is held across several unverified contracts.
- The owner is in possession of 9.3% of the total supply.
- The contract features anti-bot logic that prevents users from sending and recieving tokens more than once within a 10 second period; this does not apply to users on the whitelist.
- Anyone can approve any address to spend a specified amount of their tokens; once an allowance is set, it may be increased or decreased at any time.
- Anyone with the proper approval is able to transfer tokens from a specified address to any other address.
- The owner is able to add or remove any address from the whitelist at any time.
- The contract complies with the EIP-20 standard.
TokenVestingFactory and TokenVesting Contracts:
- Once the start date has passed, the crowdsale is active until the funding goal of 805 BNB has been met, or until the deadline has passed.
- While the crowdsale is active, users must deposit at least 0.1 BNB (up to a total contribution limit of 5 BNB per user) and in return will receive 23,238 tokens per BNB deposited.
- Users are able to claim their tokens after the publish date of the crowdsale has passed; there must be enough tokens in the contract to support the transaction.
- The owner is able to set the deadline and the publish date of the crowdsale at any time.
- The owner is able to add or remove any address from the whitelist at any time; only whitelisted users may participate in the crowdsale.
- The owner is able to withdraw all the BNB from the contract at any time.
- The owner is able to withdraw all the crowdsale tokens from the contract at any time.
General notes across all contracts:
- Anyone can use the TokenVestingFactory contract to create a new TokenVesting contract for any beneficiary address, as long as the address is not already a beneficiary for any existing TokenVesting contract.
- Vested tokens must be manually released by anyone; the tokens are always delivered to the beneficiary address.
- An initial sum of tokens can be released as soon as the vesting period begins.
- The remaining tokens are vested linearly, based on the initial release time and the release period duration specified on deployment.
- The team worked with us to implement several enhancements related to gas optimization and functionality.
- Excellent use of ReentrancyGuard to prevent re-entrancy attacks throughout the platform.
- As the contracts are implemented with Solidity v0.8.x, they are protected from overflows.
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: October 19th, 2021.
External Threat Results
Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | N/A | PASS |
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 |
Integer Over/Underflow | N/A | PASS |
Multiple Sends | 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 |
CoinracerToken Contract
($) = 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 #
+ [Int] IERC20Metadata (IERC20)
- [Ext] name
- [Ext] symbol
- [Ext] decimals
+ Context
- [Int] _msgSender
- [Int] _msgData
+ CoinracerToken (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 #
Crowdsale Contract
($) = 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
- [Prv] _setOwner #
+ 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
+ Crowdsale (Ownable, ReentrancyGuard)
- [Pub] #
- [Ext] ($)
- [Ext] updateDeadline #
- modifiers: onlyOwner
- [Ext] checkFunds
- [Ext] checkCRACEFunds
- [Ext] getBNBBalance
- [Ext] isWhitelisted
- [Ext] addWhitelisted #
- modifiers: onlyOwner
- [Ext] removeWhitelisted #
- modifiers: onlyOwner
- [Pub] invest ($)
- modifiers: onlyWhitelisted
- [Ext] getCRACE #
- modifiers: afterClosed,nonReentrant
- [Ext] withdrawBNB #
- modifiers: onlyOwner
- [Ext] withdrawCRACE #
- modifiers: onlyOwner
TokenVestingFactory and TokenVesting Contracts
($) = 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
- [Prv] _setOwner #
+ TokenVesting (Ownable)
- [Pub] #
- [Ext] getBeneficiary
- [Ext] getInitialAmount
- [Ext] getT0
- [Ext] getT1
- [Ext] getDuration
- [Ext] getReleased
- [Ext] getVestedAmount
- [Pub] release #
- [Prv] _releasableAmount
- [Prv] _vestedAmount
+ TokenVestingFactory
- [Pub] getVestingAddress
- [Int] register #
- [Pub] create #