# Problems with tokens that transfer less than amount. (Separate from fee-on-transfer issues!)

Tokens like cUSDCv3 treat transfer amount==uint256.max as 'send full balance', letting an attacker brick pool funding and donation claims with dust.

- Payout: Contest reward
- Severity: medium
- Program: Gitcoin
- Credited: jkoppel
- Disclosed: 2023-09-01
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-09-Gitcoin-judging/issues/379
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-09-Gitcoin%3AM-8
- Tags: domain:web3 impact:dos impact:integrity kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** Allo v2 fundPool and DonationVotingMerkleDistributionVaultStrategy
**Root cause:** Protocol assumes transferFrom(amount) moves exactly amount, but tokens like cUSDCv3 special-case amount==type(uint256).max to transfer only the sender's balance, so recorded accounting diverges from actual transfer.
**Steps:**
1. Attacker holds dust of a max-special-casing token (e.g. cUSDCv3) in a wallet.
2. Call `allo.fundPool(poolId, type(uint256).max)` with that token; only dust balance moves but poolAmount is set to max, permanently blocking further funding.
3. Alternatively call the donation vault deposit with `type(uint256).max` to set a recipient's claim to max, blocking all other donations of that token.
**How found:** Researcher cross-referenced the d-xo weird-erc20 list (max-amount special case) against Allo's fundPool/donation accounting, then confirmed cUSDCv3's transferInternal does `if (amount == type(uint256).max) amount = balanceOf(src)` by tracing Comet.sol delegatecall to CometExt.
**Exploitation:** Attacker sends a dust amount using amount=type(uint256).max so the token transfers only their balance while the protocol records the full max value, permanently DoSing pool funding or donation claims for that token.
**Insight:** When a protocol claims 'we support all ERC20s', grep weird-erc20 behaviors (max-amount, FOT, rebasing) against every place an amount is recorded vs. actually transferred; the max-amount case silently desyncs accounting and can permanently brick state.
