<!-- canonical: https://0xsimao.com/findings/blast-ido-pools-participation-imprecise-excessive-sold -->

# Funding cap in `IDOPoolAbstract::_basicParticipationCheck()` is imprecise and can lead to excessive tokens sold

Crit/High · Three Sigma · IDO launchpad · 7th August, 2024

Finding H-2 of the Blast IDO Pools security review.

- Protocol: https://docs.blastup.io/blastup-docs
- Report: /reports/blast-ido-pools
- Source: https://cdn.sanity.io/files/qoqld077/production/d2a7ca81740e715b604122c12dafbce599e43f2f.pdf

---

### Description

`IdoTokens` are allocated in `IDOPoolAbstract::enableIDORound()` up to `idoConfig.idoSize`. The funding cap in `IDOPoolAbstract::_basicParticipationCheck()` is performed as `newFundedUSDValue <= idoConfig.idoSize * idoConfig.idoPrice`, where `newFundedUSDValue == idoConfig.fundedUSDValue + amount * idoConfig.idoPrice`.

Firstly, `idoConfig.fundedUSDValue` has `fyToken` or `buyToken` units (see `IDOPoolAbstract::participateInRound()`), but it is summed to `amount * idoConfig.idoPrice`, which has different units as it is multiplied by the price.

Additionally, tokens are handed out according to `tokenAllocation = (amount * 10**idoConfig.idoTokenDecimals) / idoConfig.idoPrice`, but `newFundedUSDValue` is compared against `amount * idoConfig.idoPrice`, not taking into account the decimals.

### Recommendation

```solidity
function participateInRound(...) {
    ...
    uint256 tokenAllocation = (amount * 10**idoConfig.idoTokenDecimals) / idoConfig.idoPrice;
    uint256 newTotalTokens = idoConfig.fundedUSDValue + tokenAllocation;
    require(newTotalTokens <= idoConfig.idoSize, "Funding cap exceeded");
}
```

---

Related findings:

- [The domain with 0 index in Cap::_checkRemoteStateAndAdvance() is not checked for equality](https://0xsimao.com/findings/mitosis-index-remote-advance-equality): Mitosis
- [Cap::_checkRemoteStateAndAdvance() may be optimized by returning early as soon as a different epoch is found in a remote domain](https://0xsimao.com/findings/mitosis-remote-returning-soon-epoch): Mitosis
- [AaveYieldBackend.deposit() DoS when Aave pool is paused, frozen, or at supply cap](https://0xsimao.com/findings/superfluid-aave-yield-deposit-paused): Superfluid Yield Backends
- [BasicVault is incompatible with fee-on-transfer tokens](https://0xsimao.com/findings/mitosis-basic-incompatible-fee-transfer): Mitosis
