Presale.sol
Issue 01
Description
Line 73 enforces that busdLimits[0] is strictly smaller than busdLimits[1]. Some presales may wish to provide only a single contribution amount, which isn't possible with this condition.
Recommendation
Consider changing the condition to "<="
Issue 02
Description
If a malicious user sends BUSD to the contract, he can make tokenAmount
greater than the available tokenX balance, which will make the withdrawal fail.
This issue can also arise if there is no hardcap and the presale contract raised more funds than the owner has tokenX to cover.
Recommendation
Calculate tokenAmount
based on raised funds, not on BUSD balance, and make sure the owner has enough tokens to cover all amount of raised funds. Note that in these cases, users will not be able to get refunds until the presale is manually canceled.
Same issue as above on closePresale()
Issue 03
Description
onlyFactory()
modifier is not used.
Issue 04
Description
withdrawRaisedFunds() requires that
without checking if hardcap was already reached.
Recommendation
If hardcap was reached before presaleCloseAt, allow withdrawRaisedFunds to continue as the presale has ended de-facto.
Issue 05
Description
If presale was successful (softcap was reached) users' funds are locked until either the presale is canceled or the team calls withdrawRaisedFunds.
Recommendation:
Consider taking a more decentralized approach - if presale wasn't canceled or withdrawRaisedFunds after a set amount of time, users can automatically call getRefund.
Note
After hardcap is reached, investors are still able to withdraw their funds as long as the presale wasn't finalized by calling withdrawRaisedFunds. Please note, that this can create a scenario where presale bounces between filled and not filled, because users can get a refund even after hardcap was reached.
Issue 06
Description
Contract can buy shield-network token to participate in presale, call join function and sell shield network token immediately. By doing that, they can bypass the minimum amount of tokens required to participate.
Recommendation
require tx.origin to be msg.sender in order to prevent contracts from participating in presale
Issue 07
Description
BUSD name is not indicative, since the presale can raise funds in any token and not restricted to be BUSD.
Issue 08
Description
The join function checks the amount of raised BUSD using busd.balanceOf. Thus, if users erroneously send BUSD directly to the contract they will not receive tokens, but the project creator will receive their funds.
Recommendation
In withdrawRaisedFunds
transfer all excess BUSD to shield network, and in the join function perform the check using raisedFunds instead of busd balanceOf(address(this)).
Issue 09
Description
if tokenX has fees then when the presale owner transfer tokenX to the contract for distribution in withdrawRaisedFunds, the contract will receive less tokens than expected, which will guarantee that several presale participants won't be able to receive their tokens.
Recommendation
Add a sanity check that ensures that after the tokenX transfer, the tokenX balance of the presale contract is at least the expected tokenXAmount.
⚠️ Please note that in this scenario, presale does not support tokens with fees on transfer. This should be communicated to clients.
Last updated