CertiK reviewed Rich Quack (Quackpad IDO + Inqubator) on 4 Jul 2023: 8 findings, 0 critical; 3 marked fixed, 5 acknowledged.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 1 | 0 |
| Medium | 0 | 0 | 0 |
| Low | 0 | 4 | 3 |
### PresalePrivateTest #### _presalecreator In the contract `PresalePrivateTest` the role `_presalecreator` has authority over the functions shown in the list below. - addOrRemoveParticipants(): Add users into the whitelist or remove users from it - addLiquidity(): Add liquidity into `paymentToken`-`saleToken` pair - claimRaisedFunds(): Claim earning funds - claimLps(): Claim LP tokens - closePresale(): Close presale - withdrawTokens(): Withdraw sale tokens if presale is failed. Any compromise to the `_presalecreator` account may allow the hacker to take advantage of this authority to transfer the presale assets and influence on presale. #### factory In the contract `PresalePrivateTest` the role `FACTORY` has authority over the functions shown in the list below. - initialize(): Set up the initial contract parameters. Any compromise to the `FACTORY` account may allow the hacker to take advantage of this authority to set up the contract. #### backend In the contract `PresaleInqubatorTest` the role `backend` has authority over the functions shown in the list below. - calculateLotteryResults(): Calculate lottery results. Any compromise to the `backend` account may allow the hacker to take advantage of this authority to calculate lottery results. ### PresaleInqubatorTest #### _presalecreator In the contract `PresaleInqubatorTest` the role `_presalecreator` has authority over the functions shown in the list below. - addLiquidity(): Add liquidity into `paymentToken`-`saleToken` pair - claimRaisedFunds(): Claim earning funds - claimLps(): Claim LP tokens - closePresale(): Close presale - withdrawTokens(): Withdraw sale tokens if presale is failed. Any compromise to the `_presalecreator` account may allow the hacker to take advantage of this authority to transfer the presale assets and influence on presale. #### factory In the contract `PresaleInqubatorTest` the role `FACTORY` has authority over the functions shown in the list below. - initialize(): Set up the initial contract parameters. Any compromise to the `FACTORY` account may allow the hacker to take advantage of this authority to set up the contract. #### approver In the contract `PresaleInqubatorTest` the role `approver` has authority over the functions shown in the list below. - approve(): Approve the presale contract and allow investing to proceed. Any compromise to the `approver` account may allow the hacker to take advantage of this authority to approve or reject presales. #### backend In the contract `PresaleInqubatorTest` the role `backend` has authority over the functions shown in the list below. - calculateLotteryResults(): Calculate lottery results. Any compromise to the `backend` account may allow the hacker to take advantage of this authority to calculate lottery results. ### PresalePublicTest #### _presalecreator In the contract `PresalePublicTest` the role `_presalecreator` has authority over the functions shown in the list below. - addLiquidity(): Add liquidity into `paymentToken`-`saleToken` pair - claimRaisedFunds(): Claim earning funds - claimLps(): Claim LP tokens - closePresale(): Close presale - withdrawTokens(): Withdraw sale tokens if presale is failed. Any compromise to the `_presalecreator` account may allow the hacker to take advantage of this authority to transfer the presale assets and influence on presale. #### factory In the contract `PresalePublicTest` the role `FACTORY` has authority over the functions shown in the list below. - initialize(): Set up the initial contract parameters. Any compromise to the `FACTORY` account may allow the hacker to take advantage of this authority to set up the contract.
In the `invest()` function, the following line serves to set the whitelists to allow users to make an investment to purchase tokens. ```solidity if (!expandCalled && random > 0) _expand(); ``` If this logic is called, then only whitelisted users will be allowed to invest (especially in the moon round). ```solidity if (expandCalled) require(lotteryWhitelist[sender1], "LOOSE"); ``` When this whitelist is not set before users start to invest, any user can invest. In the case that the VRF random generator required to set the value `random` is set at a date later, still during the moon phase, a restriction will be applied and then only certain users will be able to invest.
The function `getCloseTimestamps()` returns an array containing the end times of each stage. However, in the case of `diamondEnd >= generalInfo.closeTime`, it returns `diamondEnd` as the end time of each stage. Even though this is only a view function, we still would like to confirm whether this matches the intended design. ```solidity if (diamondEnd < generalInfo.closeTime) { stagesEnd = [ generalInfo.openTime + 15 minutes, generalInfo.openTime + 20 minutes, generalInfo.openTime + 25 minutes, diamondEnd ]; } else { stagesEnd = [diamondEnd, diamondEnd, diamondEnd, diamondEnd]; } ```
In function `getMaxInvestment()`, the following is present to return 0 if the following criteria are fulfilled. ```solidity if (!sender.lock || sender.level == 0) return 0; ``` This will prevent users that have a status of `!sender.lock` from being able to see their max investment value.
It was noted that `minutes` were used in the contracts instead of days for numerous functions within the presales contracts.
The report names a repository or files. Open the report to see its scope.
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’s auditsSomething wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us