# All fund from Teller contract can be drained because a malicious receiver can call reclaim repeatedly

FixedStrikeOptionTeller.reclaim transfers collateral based on optionToken.totalSupply() without marking the option reclaimed, letting a malicious receiver drain all Teller funds via repeated calls.

- Payout: Contest reward
- Severity: high
- Program: Bond
- Credited: 0xcrunch
- Disclosed: 2023-06-26
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-06-bond-judging/issues/79
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-bond%3AH-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** FixedStrikeOptionTeller.reclaim (Solidity options contract)
**Root cause:** reclaim() pays out collateral proportional to optionToken.totalSupply() but never burns the option tokens nor records that the option was already reclaimed, so the same supply can be redeemed repeatedly.
**Steps:**
1. Deploy an option via Teller#deploy with receiver set to an attacker-controlled address and a call/put option.
2. Mint option tokens so totalSupply() is nonzero and collateral is deposited in the Teller.
3. Wait until option expiry.
4. Call reclaim() from the receiver address; Teller transfers payoutToken (call) or quoteToken (put) equal to totalSupply()/strike conversion.
5. Call reclaim() again repeatedly; each call transfers the same amount since supply is unchanged, draining collateral belonging to other options.
**How found:** Code review of reclaim(): noticed the payout amount derives from optionToken.totalSupply() and that no burn or per-option claimed flag exists, implying the same supply can be redeemed multiple times against a shared contract balance.
**Exploitation:** Attacker deploys a cheap option with self-controlled receiver, mints tokens to establish supply, waits for expiry, then loops reclaim() to repeatedly withdraw collateral from the shared Teller balance, draining funds backing all other option tokens.
**Insight:** When a redemption/claim function computes payout from a token's totalSupply() rather than burning the caller's balance, check whether the supply is decremented or a claimed flag is set; shared-collateral contracts make this a full-drain primitive.
