# New gALCX token denomination can be depressed by the first depositor

First depositor of a fresh gALCX vault stakes 1 wei then donates ALCX to inflate exchangeRate, rounding later depositors' shares and stealing their funds.

- Payout: Audit contest
- Severity: medium
- Program: Alchemix
- Found by: hyh
- Disclosed: 2022-07-18
- Write-up quality: 7/10
- Original: https://code4rena.com/reports/2022-05-alchemix#m-10
- Library page: http://bugbountylibrary.com/r/c4%3A2022-05-alchemix%3AM-10
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss vuln:share-inflation

**Target:** gALCX staking vault contract (Solidity)
**Root cause:** gALCX mints shares as amount*1e18/exchangeRate with no minimum first deposit or dead shares; exchangeRate is derived from balance/totalSupply, so a 1 wei first stake plus a direct ALCX donation inflates the rate and truncates subsequent mints.
**Steps:**
1. Attacker calls `stake(1)` on a fresh gALCX contract as first depositor, receiving 1 wei gALCX (exchangeRate still 1e18).
2. Attacker directly transfers e.g. `10^6 * 1e18 - 1` ALCX to the gALCX contract and calls `bumpExchangeRate()`, setting exchangeRate to ~10^6*1e18*1e18 since totalSupply is 1 wei.
3. Second depositor calls `stake(1.9*10^6 * 1e18)`; gAmount = amount*1e18/exchangeRate truncates to 1 wei gALCX.
4. Attacker and victim each hold 1 of 2 wei supply, splitting the 2.9*10^6*1e18 pool 50/50; attacker gains ~0.45*10^6*1e18 ALCX.
5. Attacker stays staked (no unstake penalty) to keep harvesting remainders of future deposits.
**How found:** Read gALCX.stake/bumpExchangeRate mint math and noticed gAmount truncation combined with exchangeRate = balance/totalSupply and no minimum first deposit, matching the known Yearn vault first-depositor inflation pattern (TOB-YEARN-003).
**Exploitation:** Attacker needs to be the first depositor of a newly deployed gALCX contract. They stake 1 wei, donate a large ALCX amount directly to the contract, and call bumpExchangeRate() to inflate the exchange rate. Every subsequent deposit is rounded down to a multiple of the inflated rate, with the truncated remainder effectively redistributed to existing shareholders (the attacker). Attacker exits via unstake() with no penalty, capturing principal from victims.
**Insight:** For any vault where shares = amount * precision / exchangeRate and exchangeRate derives from balance/totalSupply, check whether the first deposit can be 1 wei and whether a direct token transfer plus a rate-bump function lets you inflate the rate before victim deposits; the truncation then silently donates remainders to you.

