# Token:mint: infinite loop if the founders' shares sum up to 100

Token.mint loops forever when founders' ownershipPct sums to 100, since _isForFounder checks _tokenId % 100 and all 100 slots are vesting, bricking mint and auction.

- Payout: Contest reward
- Severity: medium
- Program: Nouns Builder
- Credited: zzzitron
- Disclosed: 2022-11-03
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-09-nouns-builder-findings/issues/347
- Library page: https://bugbountylibrary.com/r/c4%3A2022-09-nouns-builder%3AM-03
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:dos

**Target:** Token.sol mint() / _isForFounder()
**Root cause:** _isForFounder uses baseTokenId = _tokenId % 100 to look up the scheduled recipient; when founders' shares fill all 100 slots, every tokenId maps to a vesting founder, so the do-while in mint() never exits.
**Steps:**
1. Deploy Token with two founders each ownershipPct=50, vestExpiry=4 weeks.
2. Confirm totalFounderOwnership()==100 and tokenRecipient[0..99] all set.
3. Call auction.unpause() to trigger Token.mint().
4. mint() do-while calls _isForFounder(tokenId) which returns true for every tokenId since baseTokenId=_tokenId%100 always hits a vesting slot.
5. Loop runs until out-of-gas revert; auction cannot mint.
**How found:** Code reading of mint()'s do-while loop and _isForFounder's modulo-100 lookup; noticed that filling all 100 tokenRecipient slots makes the loop non-terminating, then wrote a Foundry PoC with two 50% founders.
**Insight:** When a loop's exit condition depends on a modulo-indexed lookup table, check whether the table can be fully populated so no index ever returns false; founder/share scheduling with %100 is a classic case.
