# Zero strike call options can be systemically used to steal premium from the taker

Zero-strike call options with ERC20s that revert on zero transfers become unexercisable, letting malicious makers collect premium then reclaim assets at expiry.

- Payout: Contest reward
- Severity: high
- Program: Putty
- Credited: hyh
- Disclosed: 2022-06-27
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-06-putty-findings/issues/418
- Library page: https://bugbountylibrary.com/r/c4%3A2022-06-putty%3AH-04
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic

**Target:** PuttyV2 options exercise/fillOrder logic
**Root cause:** exercise() unconditionally calls safeTransferFrom for order.strike without checking strike > 0; tokens that revert on zero-value transfers make exercise impossible.
**Steps:**
1. Maker creates short call order with order.strike = 0 and baseAsset = ERC20 that reverts on zero transfers.
2. Taker fills order, paying premium to maker via `ERC20(baseAsset).safeTransferFrom(taker, maker, premium)`.
3. Taker attempts `exercise(order, ...)`; code hits `ERC20(order.baseAsset).safeTransferFrom(msg.sender, address(this), order.strike)` with strike=0, reverting.
4. Option expires unexercised; maker calls withdraw() and recovers collateral via `_transferERC20sOut`/`_transferERC721sOut`.
5. Maker keeps premium for free.
**How found:** Warden reasoned about edge cases of strike=0 combined with weird ERC20 semantics (revert-on-zero-transfer), noting zero-strike calls are common and premium substantial, creating information asymmetry exploitable by maker.
**Exploitation:** Malicious maker selects a baseAsset ERC20 that reverts on zero transfers, lists a zero-strike call, collects the substantial premium from the taker, and waits for expiry since exercise always reverts; then withdraws collateral.
**Insight:** When auditing option/derivative protocols, cross-reference valid parameter edge cases (strike=0, amount=0) against weird-ERC20 behaviors like revert-on-zero-transfer; any unconditional transfer of a user-controlled amount can brick a code path and turn into a griefing/theft vector.
