# Division by zero error causes KangarooVault to be DoS with funds locked inside

KangarooVault.getTokenPrice divides by totalSupply which can reach zero after all withdrawals, reverting deposits and locking remaining funds permanently.

- Payout: Contest reward
- Severity: high
- Program: Polynomial Protocol
- Credited: peakbolt
- Disclosed: 2023-08-01
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-03-polynomial-findings/issues/160
- Library page: https://bugbountylibrary.com/r/c4%3A2023-03-polynomial%3AH-06
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:dos

**Target:** KangarooVault.getTokenPrice() / initiateDeposit()
**Root cause:** getTokenPrice() divides totalFunds by getTotalSupply() without handling totalSupply == 0, which occurs when all vault tokens are burned while residual funds remain after positions close.
**Steps:**
1. Open a position via `kangaroo.openPosition(amt, 0)`, execute and clear pending open orders.
2. User initiates partial withdrawal `initiateWithdrawal(user_1, 5e23)` and `processWithdrawalQueue(1)`.
3. Close all positions: `closePosition(amt, 1000000e18)`, execute and clear pending close orders.
4. `processWithdrawalQueue(1)` again, reducing totalSupply to zero while residual funds remain.
5. Call `initiateDeposit(user_1, 5e23)` — reverts due to division by zero in getTokenPrice().
6. Vault is DoS'd; remaining SUSD (168969) locked since no VaultTokens exist to burn for withdrawal.
**How found:** Code reading of getTokenPrice() noting the divWadDown(totalSupply) branch when positionId == 0 and totalFunds != 0; hypothesized totalSupply could hit zero after full withdrawal while funds remain, then built a PoC test to confirm.
**Exploitation:** No attacker capital needed; the DoS arises naturally from normal user flow (open position, partial withdraw, close position, final withdraw) leaving totalSupply at zero with residual funds. Subsequent deposits revert, permanently locking funds.
**Insight:** In vault share-price math, check the zero-supply branch separately from zero-funds; residual dust after closing positions plus full share burn creates a permanent division-by-zero lock because recovery paths (deposits) also call the same price function.
