# [gALCX.sol] Attacker can make the contract unusable when totalSupply is 0

Donating ALCX directly to gALCX while totalSupply is 0 makes bumpExchangeRate divide by zero, bricking stake, unstake and migrateSource.

- Payout: Audit contest
- Severity: medium
- Program: Alchemix
- Found by: TerrierLover
- Disclosed: 2022-07-18
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2022-05-alchemix#m-11
- Library page: http://bugbountylibrary.com/r/c4%3A2022-05-alchemix%3AM-11
- Tags: area:web3 domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity vuln:accounting-error vuln:dos

**Target:** gALCX staking contract (Solidity)
**Root cause:** bumpExchangeRate divides donated balance by totalSupply without guarding totalSupply == 0, so a direct token transfer before any stake reverts the rate update and every function that calls it.
**Steps:**
1. Deploy gALCX (totalSupply == 0).
2. Attacker transfers ALCX directly to the contract, bypassing stake(), so `alcx.balanceOf(address(this)) > 0` while totalSupply stays 0.
3. bumpExchangeRate hits `exchangeRate += (balance * exchangeRatePrecision) / totalSupply;` and reverts on division by zero.
4. stake() reverts for all users; owner's migrateSource() also reverts since it calls bumpExchangeRate.
**How found:** Reading bumpExchangeRate's balance check, noticed it only tests balance > 0 and not totalSupply, so a donation path bypasses the stake accounting invariant.
**Exploitation:** Attacker needs only a direct ERC20 transfer of any ALCX amount to a freshly deployed gALCX before the first stake; the resulting divide-by-zero permanently reverts stake/unstake/migrate until redeployment.
**Insight:** When a contract derives exchange rate from token balance, check the zero-supply branch: direct ERC20 donations can satisfy balance>0 while totalSupply==0, turning a division into a permanent DoS on first deposit.

