# Reentrancy in settleAuction(): malicious publisher can bypass index timelock mechanism, inject malicious index, and rug the basket

settleAuction() calls withdrawBounty() before clearing auctionOngoing, letting a malicious publisher reenter via a malicious bounty ERC20 to inject malicious index weights and drain the basket.

- Payout: Audit contest
- Severity: high
- Program: Kuiper
- Found by: kenzo
- Disclosed: 2022-01-26
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2021-09-defiprotocol-findings/issues/31
- Library page: https://bugbountylibrary.com/r/c4%3A2021-09-defiprotocol%3AH-03
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:chained vuln:business-logic vuln:governance vuln:reentrancy

**Target:** settleAuction() / withdrawBounty() in DeFi basket protocol
**Root cause:** settleAuction() performs the external withdrawBounty() transfer before setting auctionOngoing = false, violating checks-effects-interactions and leaving reentrancy window open.
**Steps:**
1. Publisher contract proposes valid new index and bonds auction.
2. Add bounty of malicious ERC20 whose transfer() reenters.
3. Call `settleAuction()` with correct params and malicious bounty id.
4. Inside withdrawBounty() transfer, malicious token reenters `settleAuction()` with empty params; prior effects satisfy checks, setNewWeights() runs and sets pendingWeights.pending = false.
5. Still in transfer, call `publishNewIndex()` with attacker-favorable weights; succeeds since pending is false.
6. Original settleAuction() resumes and calls setNewWeights(), applying malicious pending weights.
7. Publisher calls `burn()` on shares, transferring all basket tokens to himself.
**How found:** Manual code review noting withdrawBounty() external call precedes auctionOngoing = false, then constructing a malicious bounty token to reenter and abuse publishNewIndex() gating on pendingWeights.pending.
**Exploitation:** Malicious publisher contract bonds a valid auction, supplies a malicious ERC20 bounty whose transfer() reenters settleAuction() to clear pendingWeights.pending, then calls publishNewIndex() with drain-enabling weights; outer settleAuction() applies them, then publisher burns shares to extract all underlying funds.
**Escalation:** Reentrancy bypasses the index timelock, letting publisher inject arbitrary weights and drain entire basket in one transaction.
**Insight:** When a settle/finalize function makes an external token transfer before clearing its in-progress flag, a malicious bounty/reward token can reenter; check whether reentering lets you reset a 'pending' guard that gates a privileged publish/set function.

