# WrappedIbbtcEth contract will use stalled price for mint/burn if updatePricePerShare wasn't run properly

WrappedIbbtcEth uses a stale externally-pushed pricePerShare for mint/burn, letting a user mint cheap before an update and burn after for risk-free profit.

- Payout: Audit contest
- Severity: high
- Program: BadgerDAO
- Found by: hyh
- Disclosed: 2021-12-16
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-10-badgerdao-findings/issues/86
- Library page: https://bugbountylibrary.com/r/c4%3A2021-10-badgerdao%3AH-03
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:business-logic vuln:oracle-manipulation

**Target:** WrappedIbbtcEth ERC20 wrapper contract (mint/burn/transfer)
**Root cause:** pricePerShare is updated only by an externally-run updatePricePerShare script and is consumed by balanceToShares in mint/burn/transfer with no staleness check, so a stalled update leaves an outdated price in use.
**Steps:**
1. Monitor SetPricePerShare events; detect that updatePricePerShare has not run for a long period while market price moved.
2. Call `mint()` while contract pricePerShare is stale but favorable relative to market.
3. Wait for the off-chain script to call `updatePricePerShare` to refresh pricePerShare.
4. Call `burn()` at the updated pricePerShare to realize risk-free profit at the contract's expense.
**How found:** Code reading of WrappedIbbtcEth: noticed pricePerShare is set only by an externally-run updatePricePerShare and used directly in balanceToShares for mint/burn/transfer without any staleness guard, making the contract dependent on off-chain script reliability.
**Exploitation:** Attacker watches the SetPricePerShare event and the gap since last update; if the market moved while pricePerShare is stale, mint at the outdated rate, wait for the next update, then burn at the corrected rate, extracting value from contract holdings.
**Insight:** When a contract caches an externally-pushed oracle/price variable for gas savings, check every consumer for a max-staleness guard; a missing one turns any liveness failure of the updater into a free mint/burn arbitrage.
