Opus finding
DopplerERC20V1.initialize: maxTotalPreMint cap not enforced when balanceLimit not configured but allocations exist; off-by-one allows `vestedTokens == initialSupply`
mediumapi-contracthigh
- src/tokens/DopplerERC20V1.sol:244-247
- src/tokens/CloneERC20.sol:156-162
In `CloneERC20.initialize`, the check is `vestedTokens < initialSupply` (strict). In `DopplerERC20V1.initialize`, the check was relaxed to `vestedTokens <= initialSupply`, which allows the entire initial supply to be allocated to vesting recipients, leaving 0 tokens to the non-vested `recipient` (the pool/migrator). This is likely unintended divergence from the sibling token: if `vestedTokens == initialSupply`, then `_mint(recipient, initialSupply - vestedTokens)` mints 0 to the pool recipient, breaking pool initialization downstream. The two clones diverged silently.
Recommendation
Either align with CloneERC20 (`<`) or remove the redundant check entirely since the maxTotalPreMint check already caps vestedTokens at 0.8 * initialSupply. Document the intent.