
Date: September 15, 2026
Chain: Ethereum
Loss: 2,900 aEthrsETH, about $7.8M
Class: an authorization check that passed whenever a contract was asked to call itself
At 04:38:47 UTC on September 15, 2026, the first transaction in Ethereum block 25980525 didn't come from the attacker who had found the bug. It came from Yoink, a generalized MEV bot that copies profitable transactions out of the public mempool and lands them first. Yoink's copy pulled 2,900 aEthrsETH out of a single user's Gnosis Safe, converted it to rsETH, paid the block builder 18.93 ETH for the top slot, and sent 2,882.37 rsETH, worth about $7.8M, to an address the bot's operator controlled. The attacker who wrote the exploit lost the race for the big prize.
Safe's core contracts weren't the bug and never failed. The owner had enabled a third-party strategy module to manage a leveraged rsETH position, and that module trusted a router contract whose permission check returned true whenever the router was told to call itself. Anyone who knew that could ask the router to call itself, then ask the module to run arbitrary code inside the Safe.
rsETH is Kelp DAO's liquid restaking token. This Safe, at 0x40E93a52F6Af9fCD3b476aeDADD7FeABD9f7AbA8, held it as aEthrsETH, the Aave deposit receipt for rsETH, inside a leveraged position: rsETH supplied as collateral on Aave with WETH borrowed against it. The DeFiHackLabs review log records the Safe's balance just before the drain at about 53,402.66 aEthrsETH, so the 2,900 that left in block 25980525 was about 5% of the position. Reading the Safe's own getOwners() and getThreshold() on-chain today returns three owners and a threshold of one, which means any single owner can sign and send a transaction for it.
Running a leveraged position like that takes frequent, precise transactions, so the owner automated it with custom contracts. A router at 0x4f0055926c839D1d960a82CBF84E2eE933958ebC accepted batched instructions, and a strategy executor module at 0xeA18B13d11f705a68F0954f637949e1eaA7AC4ca was enabled on the Safe to carry them out. Behind the module sat a RecipeExecutor that ran the actual steps. The researcher who reproduced the attack describes the whole set as "a private DeFi-Saver fork with mined selectors", where DeFi Saver is an open-source automation system that strings actions such as withdraw, swap and repay into a single recipe. None of the router, module, RecipeExecutor or action executor contracts has verified source on Etherscan.
A Safe module is an extension the owner installs on purpose. Once enabled, a module can call execTransactionFromModuleReturnData on the Safe and execute transactions without any owner signatures, which is the whole point of automation. That call takes an operation argument: 0 makes an ordinary call from the Safe, and 1 makes a DELEGATECALL, which runs the target's code with the Safe's own storage and balances as if it were the Safe's logic. The module's own access control becomes the Safe's access control for everything that module can reach, and with DELEGATECALL in reach, that's everything the Safe owns.
The router's source was never published, so no verified code exists to quote here, and the analysis rests on SlowMist's reading of the deployed bytecode and the DeFiHackLabs reproduction. The router exposed multicall(address _contract, bytes[] _data), which forwards a batch of calls to a target contract after an authorization check. According to SlowMist, that check, _isAuthorized, returned true unconditionally whenever _contract was the router's own address. The check was meant to ask whether the caller had the right to direct the target, and for one target it stopped asking.
On its own, a router calling itself sounds harmless, since the only code it can reach is its own. The danger came from the second relationship in the stack. The strategy module trusted the router as a legitimate source of instructions, so any call that arrived from the router's address passed the module's check. Each contract's gate made sense in isolation, and together they formed a path that let a stranger borrow the router's identity.
The attack used that exception twice. An outer multicall named the router itself as the target, so it passed. Inside it, a second multicall targeted the strategy module, and since that call now came from the router, the module accepted it. The module then called execTransactionFromModuleReturnData with the RecipeExecutor as target and operation 1. The DeFiHackLabs PoC includes a negative control that sends the same module payload without the self-referential wrap, and that version reverts, which isolates the self-target exception as the hole. It's like a building's front desk that checks every visitor's badge except for anyone who says they work at the front desk.
BlockSec described the cause as insufficient authorization validation in an executor contract associated with a Safe module, Blockaid called it module-authorization abuse rather than a Safe core or owner-key bug, and SlowMist and AstraSec traced it to the same multicall helper. Kelp DAO confirmed its own contracts and rsETH's backing were unaffected.
The attacker built a recipe that would pull the Safe's aEthrsETH out of Aave and push it into a freshly created Uniswap v4 pool, equipped with a hook and paired with a worthless token called Permissionless Attacker Token (PAT), where it could be converted to transferable rsETH. Then the attacker broadcast that transaction to the public mempool.
Yoink simulated the payload, saw the profit, and submitted its own version, sent from 0xFDe0...455A to its bot contract and landing at position zero in the block. The trace of Yoink's transaction, 0x0e7680b06cb8a6f86c149d9ba90d98e3d334e7b072dde03909d43fcfd98a8705, shows the whole chain: the router calling itself, the router calling the module, the module delegating the Safe into recipe code that unwound its Aave position through Uniswap v4. The token transfers on Blockscout show 2,899.99 aEthrsETH burned from the Safe, the same amount minted to a helper contract and redeemed from Aave as rsETH, which then went to Yoink's bot. Yoink routed 17.63 rsETH through the Uniswap v4 PoolManager for 18.95 ETH, passed 18.93 ETH, roughly $46,000, to the block builder, and sent the remaining 2,882.37 rsETH to 0xC70f00CD7E461686b04B0E912E309becA8b80ea0. Parameter reported that the original exploit transaction landed later in the same block and failed.
The module stayed enabled for another 81 minutes, and the Safe's transfer history on Blockscout shows others using it. At 05:24:47 UTC, a transaction from 0x41a1...F27b took 50 aEthrsETH. At 05:43:35 UTC, in block 25980849, the address SlowMist names as the attacker, 0x2f7e...2f67, minted a fresh supply of PAT and pulled 9 aEthrsETH, which arrived at that address as rsETH, and it took another 0.5 at 05:49:23 UTC. Between 05:54:23 and 05:55:23 UTC, thirteen more transactions from three other senders each took about 0.5 aEthrsETH the same way. The DeFiHackLabs write-up describes the later attempts as copycats, and next to the 2,900 taken first, they were small.
At 06:00:11 UTC, in block 25980931, the Safe's own owner transaction disabled the strategy executor module and one other module. At 06:37:11 UTC the Safe repaid about 248 WETH of its Aave debt, and at 07:20:23 UTC a second owner transaction disabled nine more modules. Defimon raised the first public alert about forty minutes after the main drain.
Kelp DAO put a 24-hour wallet-level pause on Yoink's receiving address within about two hours, saying "Out of an abundance of caution, we've placed that address under a temporary 24-hour pause" and that minting, withdrawals and integrations continued as normal. The pause mattered because rsETH is Kelp's own token, and it kept the 2,882.37 rsETH from moving while the situation was assessed.
On September 16 at 10:38:35 UTC, after a 1 rsETH test transfer, the receiving address sent 2,881.37 rsETH in one transfer to 0x8c2AEcCef3B3634D039c96993577F80D3278FEe8. That address is one of the three owners the victim Safe lists on-chain, and it's the account that has submitted the Safe's own transactions, including both module-disabling transactions on September 15. The on-chain record therefore shows nearly all of Yoink's take going back to the Safe's owner about 30 hours after the drain. Neither Yoink's operator nor the Safe's owner has made a public statement that we could find explaining the terms as of October 20, 2026, and Unchained notes the precedent of a January MEV builder that returned most of a Makina exploit while keeping a 10% bounty under the SEAL Whitehat Safe Harbor. As of October 20, 2026, the Safe still held about 50,278.79 aEthrsETH on Blockscout.
Olympix reads a contract system the way an attacker does, as states, transitions and entry points, and it works on the code a team actually ships, so a router with no verified source on a block explorer is no obstacle. In this setup, the state that matters is the Safe's balance sheet, and the only entry points that can touch it without signatures are the paths that end in execTransactionFromModuleReturnData. The engine maps every path from a public function to that call, keeps the feasible ones, and then keeps only those that can reach the invariant, which leaves a short list running through the router's multicall and the module's executor.
Olympix's static analysis surfaces the signal on that short list: a public entry point that forwards caller-supplied calldata toward a DELEGATECALL in the Safe's context, guarded by an authorization check whose outcome the caller controls through the target argument. In plain words, the router asks who the call is for before it asks who's calling, and the caller gets to pick the answer. Olympix has flagged this class of caller-controlled arbitrary call before in other codebases.
BugPoCer takes that path and tests it against the rule the whole automation stack depends on. Running Counterexample-Guided Invariant Refutation from the system outward, it infers the invariant in one sentence: only an address the Safe's owner authorized should ever be able to make the module execute code inside the Safe. It then executes call sequences from an arbitrary outside address into the router, varying targets and nesting, until one reaches the Safe. The DeFiHackLabs negative control shows what that search runs into along the way: the module payload sent through the router without the self-referential wrap reverts, and a multicall that names the router as its own target, wrapping a second multicall aimed at the module, gets through.
The counterexample for this exploit would contain exactly those state changes: a fresh address with no role, an outer multicall with the router as target, an inner multicall with the module as target, execTransactionFromModuleReturnData called with operation 1 into recipe code the caller supplied, and the Safe's aEthrsETH balance falling while an outside address's rsETH balance rises. The minimal conditions are just two: the module is enabled on the Safe, and the module trusts the router. BugPoCer returns that sequence with a generated Forge test that replays it on a fork, the same shape as the DeFiHackLabs PoC and its negative control, and it hands that to the team as a failing test rather than a theory.
Because the engine runs automatically in development, at every merge and before release, the change that added the self-target shortcut to _isAuthorized would have been tested against the same invariant at the merge that introduced it, before the module was ever enabled on a Safe holding real collateral. The router, the module and the recipes they run would each carry a standing view of every path that reaches the Safe, in development instead of in a public mempool where anyone, attacker or bot, could take it.
A Safe's multisig protects the wallet only as far as its enabled modules do, because every module carries the power to act without signatures. This owner's Safe was sound, and the loss came through a pair of contracts written to save it work, through an exception in a permission check that only mattered when the router was asked to call itself. If your contracts can execute code inside a wallet or vault on someone's behalf, test every path to that power before the module goes live, and book a technical walkthrough.
Protocol: Safe wallet (Safe 1.3.0 core contracts, not at fault) with a third-party strategy router and executor module enabled by its owner
Chain: Ethereum
Date: September 15, 2026, 04:38:47 UTC
Loss: 2,900 aEthrsETH, about $7.8M (2,882.37 rsETH to Yoink's receiving address)
Victim Safe: 0x40E9...AbA8
Safe owner that received the rsETH (September 16): 0x8c2A...FEe8
Vulnerable router (source unverified): 0x4f00...8ebC
Strategy executor module (source unverified): 0xeA18...C4ca
Attacker (per SlowMist): 0x2f7e...2f67
Attacker's 9 aEthrsETH pull (block 25980849): 0xb95a...6df5
50 aEthrsETH follow-on pull (05:24:47 UTC): 0xffbc...4f9a
Yoink sender: 0xFDe0...455A
Yoink MEV bot: 0x80BF...D4e4
Yoink receiving address (paused by Kelp DAO): 0xC70f...0ea0
Drain tx (Yoink, first in block): 0x0e76...8705
Block: 25980525
Module disabled by owner (06:00:11 UTC): 0x9443...35dd
Nine more modules disabled (07:20:23 UTC): 0x8938...be64
Onward rsETH transfer to the Safe owner (September 16, 10:38:35 UTC): 0xe161...0c6e
Defimon Alerts: original alert, September 15, 2026
SlowMist: root cause analysis of the multicall self-reference bypass
DeFiHackLabs PR #1262: RsETHSafeModule nested self-referential multicall PoC
Unchained: A Bot Robbed the Hacker Who Drained $7.8 Million in rsETH From a Safe Wallet
Cointelegraph: MEV Bot Front-Runs $7.7M Ethereum Wallet Exploit
Crypto Times: $7.8M rsETH Drained From Ethereum Safe Wallet, MEV Bot Yoink Front-Runs the Exploit