Comment on page
fairLaunchToken.sol
Type | Severity | Location | Status |
Logical Issue | High | initializePresale | Resolved |
Description
There is no guarantee that the owner deposits will satisfy the presale and liquidity rates.
Type | Severity | Location | Status |
Best Practice | Informational | initializable | Resolved |
Description
The name of the function is misleading. A more appropriate name could be
onlyBeforeInitialized
.Type | Severity | Location | Status |
Best Practice | Informational | contribute | Resolved |
Description
Use a modifier instead of the presale
require
statement for better readability.Type | Severity | Location | Status |
Volatile Code | Medium | contribute | Resolved |
Description
The
investor
array's size is limitless. Iterating over an unbounded array may cause the transaction to hit the block gas limit.Recommendation
Use a mapping to track contributions.
Type | Severity | Location | Status |
Logical Issue | Medium | contribute | Resolved |
Description
safeTransferFrom
does not support withFeesOnTransfer
. Hence, when calling refund, users will receive their original transfer amount without deducting fees.Type | Severity | Location | Status |
Best Practice | Medium | claim, finalize | Resolved |
Description
The functions call external contracts, exposing themselves to potential reentrancy attacks.
Recommendation
Follow check-effect interactions pattern.
Type | Severity | Location | Status |
Volatile Code | High | withdrawContribute | Resolved |
Description
The function does not change the user's deposit value, hence any user can withdraw their deposit multiple times and drain the contract.
Recommendation
Add a require statements that makes sure the user can withdraw their deposit and set
deposits[msg.sender]
to 0 after the withdrawal.Type | Severity | Location | Status |
Logical Issue | Low | withdrawContribute | Resolved |
Description
The function does not remove the user from the
investors
array.Type | Severity | Location | Status |
Owner Capabilities | Low | finalize | Resolved |
Description
The owner can lock funds in the contracts by never calling this function if the presale exceeds
softcap
Type | Severity | Location | Status |
Logical Issue | High | finalize | Resolved |
Description
listingRate
does not subtract the fees taken from the amount listed. Consequently, users may be unable to withdraw their tokens from the contract as the amount of tokens listed does not match the actual amount of tokens in the contract.Type | Severity | Location | Status |
Logical Issue | High | finalize | Resolved |
Description
The contract multiplies
listingRate
by the amount of amount to get the number of tokens. Therefore, listingRate
should be calculated as token/ETH (token per ETH). However it is currently calculated as ETH/token (ETH per token)Type | Severity | Location | Status |
Volatile Code | Informational | finalize | Not Resolved |
Description
The function calls
safeTransfer
multiple times. However, these calls may fail by the recipient, reverting the entire transaction.Recommendation
Consider wrapping these calls inside try-catch or change the transfer mechanism into a
withdraw
function that will be called by the recipients.Type | Severity | Location | Status |
Logical Issue | Low | finalize | Resolved |
Description
If a liquidity pool already exists, there may unrecoverable leftover tokens in the contract.
Type | Severity | Location | Status |
Logical Issue | High | getVestedAmount | Resolved |
Description
return user.mul(listingRate);
listingRate
is multiplied by a factor.Type | Severity | Location | Status |
Volatile Code | Medium | getVestedAmount | Resolved |
Description
The function may be called anytime. Should the function be called before
presaleEndTimestamp
, (now - presaleEndTimeStamp)
will underflow.Type | Severity | Location | Status |
Logical Issue | High | withdrawContribute | Resolved |
Description
deposits[msg.sender] is zeroed and then sent out as the value, so users will always withdraw 0 tokens - the value must be kept aside before zeroing it out.
deposits[msg.sender] = 0;
Address.sendValue(msg.sender, deposits[msg.sender]);
Type | Severity | Location | Status |
Logical Issue | High | finalize | Resolved |
Description
A malicious user can send extra tokens to the contract and prevent this function from ever succeeding.
require(IBEP20(buyToken).balanceOf(address(this)) <= maxOwnerReceive, "too much");
IBEP20(buyToken).safeTransfer(owner(), IBEP20(buyToken).balanceOf(address(this)));
Recommendation
Find a use for the leftover funds - should they go to blitz? To liquidity? To holders?
Last modified 1yr ago