Set Protocol's ETHMACOAPY RebalancingSetTokenV3 drained for ~4.05 WETH (tx1) on Ethereum via the same `actualizeFee()` divCeil rounding, with a donation step widening the rounding edge from one unit to eleven.
Security ·
Logged as “2026-10-06: A Second Rebalancingsettokenv3 Vault Ethmacoapy Hit By The Same Permissionless Actualizefee Divceil Rounding The Attacker Issues The Rebalancing Set Then Donates The Residual Base Set Into The Vault Own Backing So The Zero Fee Recompute Bumps Unitshares From 12253 To 12264 Then Redeems The Same Quantity For More Collateral Than Was Deposited The 116000 Weth Issueredeem Size Supplied Fee Free By An Aave V3 Fork Flash Loan on SetProtocol ETHMACOAPY”.
A second RebalancingSetTokenV3 vault (ETHMACOAPY) shares the same actualizeFee() divCeil rounding bug as the SetProtocol vault drained earlier the same day, but the surrounding flow is shaped differently. The vault bytecode matches the first vault byte for byte (matching extcodehash), so the actualizeFee() logic is identical and the trace confirms it live: FeeActualization(..., profitFee: 0, streamingFee: 0) and IncentiveFeePaid(..., newUnitShares: 12264) against a stored value of 12253. A fee of zero still moved the unit share by eleven, not one.
The amplification is a donation. After issuing the rebalancing set, the attacker pushes the residual baseSet balance into the rSet's own Vault backing with Core.deposit and Core.internalTransfer, minting no new rSet. currentSetAmount rises while totalSupply is unchanged, so the ceil re-derivation inside actualizeFee() jumps unitShares from 12253 to 12264. Issuing costs 12253 base-set per naturalUnit; redeeming the same quantity after actualizeFee pays 12264 per naturalUnit. The 11-unit gap, multiplied by the issued quantity, is the profit.
ETHMACOAPY's currentSet is a single-component set whose only component is WETH, so issuing and redeeming the base set is a pure WETH in and out. There is no intermediate token swap.
The gain scales linearly with the issue size. To turn the 11-unit rounding edge into roughly 4 WETH, the attacker raises 116,000 WETH of working capital for one atomic block. The on-chain transaction borrows it fee-free from an Aave-v3-fork lending pool and repays exactly 116,000 WETH principal with zero premium, confirmed in the trace. Inside one transaction, the attacker deposits the borrowed WETH, mints the base set, issues the rSet at the floor value 12253, donates the residual base set into the rSet's own Vault backing, calls actualizeFee(), redeems the rSet against the new value, withdraws the base set to WETH, repays the lender, and forwards the surplus to the attacker EOA.
A second, independent transaction two blocks later repeated the exact pattern from a different EOA, with a different attack contract, and removed a further ~4.062 WETH. The full incident total reaches ~8.11 WETH across the two EOAs. The reconstruction captures tx1 only, with tx2 standing on its own against the same vault.
DeFiHackLabs records a loss of 4.047988247781965824 WETH to the attacker in tx1 (reproduced to the wei) on Ethereum, with tx2 adding ~4.062 WETH for a combined ~8.11 WETH. The on-chain attack transaction for tx1 is 0xb54c77dae4c5ff8664779bacfb56d75242f39005b0b7778109d2f9033b9e8fc2, mined on 2026-10-06; tx2 is 0x1dc6b9f18c362192397e8483088f7957622a9323fd93ed2a22073bf309c8e08a.
The fix is the same as the first Set Protocol incident. actualizeFee() should not run when the fee minted is zero, and the stored value should be derived from the same arithmetic on issue and on the zero-fee recompute, so a no-op recompute cannot move the rate. Beyond that, a residual-collateral donation should not be allowed to widen the rounding edge by manipulating the numerator of the ceil re-derivation.
Query every incident yourself — free, no signup
Updated 11 Nov 2026. Figures are as reported by the sources listed above and are not independently verified.