# exitTempusAMM can be made to fail

Attacker frontruns exitTempusAMM by sending 1 wei of LP tokens to the controller, breaking a strict balance==0 assert and blocking all exits.

- Payout: Audit contest
- Severity: medium
- Program: Tempus Finance
- Found by: cmichel
- Disclosed: 2021-11-08
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-10-tempus-findings/issues/21
- Library page: https://bugbountylibrary.com/r/c4%3A2021-10-tempus%3AM-01
- Tags: area:web3 domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** TempusController.exitTempusAMM / TempusAMM LP token
**Root cause:** _exitTempusAMM asserts tempusAMM.balanceOf(address(this)) == 0 after redeeming lpTokensAmount, assuming the contract holds no other LP shares; any pre-existing dust balance breaks the invariant.
**Steps:**
1. Attacker observes a pending exitTempusAMM tx in mempool
2. Attacker frontruns by transferring 1 wei of TempusAMM LP tokens to the TempusController address
3. Victim's exitTempusAMM executes; after redeeming lpTokensAmount the contract still holds 1 wei
4. assert(tempusAMM.balanceOf(address(this)) == 0) reverts, failing the exit
**How found:** Code review of _exitTempusAMM spotted the strict balance==0 assert and reasoned that any external party could donate dust LP shares to the controller to violate it.
**Exploitation:** Frontrun each exitTempusAMM call with a minimal LP token transfer to the controller, causing the post-exit balance assert to revert and making the exit function unusable for all users.
**Insight:** Strict equality asserts on token balances held by a shared contract are griefable: anyone can donate dust to break the invariant. Look for `balanceOf(address(this)) == 0` style checks in exit/withdraw paths.
