Calculated from recorded token losses using historical USD prices at the incident time.
0x0eb8f8d148508e752d9643ccf49ac4cb0c21cbad346b5bbcf2d06974d31bd5c40x52d69c67536f55efefe02941868e5e762538dbd6EthereumOn Ethereum mainnet block 19213947, transaction 0x0eb8f8d148508e752d9643ccf49ac4cb0c21cbad346b5bbcf2d06974d31bd5c4 exploited the unverified auction-style contract at 0x52d69c67536f55efefe02941868e5e762538dbd6. The adversary EOA 0x145766a51ae96e69810fe76f6f68fd0e95675a0b routed the attack through helper contract 0x8d4de2bc1a566b266bd4b387f62c21e15474d12a, which repeatedly reentered makeBid() while receiving ETH refunds from the victim. The result was a deterministic drain of 11.160974999999999960 ETH from the victim and a net adversary profit of 11.129458888958904998 ETH after gas.
The root cause is a reentrant self-bidding flaw. The victim refunds the currently tracked bidder by making an external ETH call before the bid state is made safe against the same bidder immediately bidding again. Because the tracked bidder can be an attacker-controlled contract, the attacker can receive the refund, query the new minimum bid, and reenter makeBid() with a much smaller amount while still collecting the larger refund amount.
The victim is an unverified ETH bidding game. Publicly observable behavior and the decompilation reference show that it exposes at least makeBid() (0xf30e3658), owner(), claim(), and a getter at selector 0x97d54cf7 that returns the next minimum bid derived from the current bid state. The exploit depends on that getter and on the fact that the victim already held ETH and tracked an existing bidder before the seed transaction.
The pre-state was public. Before the exploit transaction, the victim already pointed at prior bidder 0x1298ef04e9e878dae51e605816ce3e6a99ad9b80, and the next minimum bid was 183750000000000 wei. The victim also held more than 30 ETH, making the recursive drain economically meaningful. A prior live transaction against the same victim, 0xaae44586bdbde1179c990aa64a1b0f2d20044cabf108591f35ea15cc1cdff45c, showed the same class of behavior was already visible on-chain.
The vulnerability class is a reentrancy-enabled accounting failure in bid replacement logic. A safe auction update must preserve the invariant that a bidder cannot withdraw more ETH during a bid transition than the incremental capital that bidder contributes to that transition. This victim violates that invariant by refunding the currently recorded bidder through an external ETH call before the victim has sealed state against same-bidder reentry.
The exploit does not require privileged access, private keys, or hidden off-chain state. Any actor able to deploy a payable helper contract and call the victim can attempt the sequence. The critical breakpoint is inside makeBid(): the victim transfers ETH to the current bidder, the callback executes attacker code, the attacker queries selector 0x97d54cf7 to learn the smaller next minimum, and then reenters makeBid() so the same address remains the bidder while capital at risk shrinks. Repeating that loop drains the victim balance.
The collector trace shows the attack starting with a top-level call from the adversary EOA to its helper with 0.6 ETH, followed by the helper's first bid of 0.294 ETH into the victim:
Origin: seed transaction trace
SM Address: 0x8d4de2bc1a566b266bd4b387f62c21e15474d12a, caller:0x145766a51ae96e69810fe76f6f68fd0e95675a0b,target:0x8d4de2bc1a566b266bd4b387f62c21e15474d12a is_static:false, transfer:Transfer(600000000000000000), input_size:4
SM Address: 0x52d69c67536f55efefe02941868e5e762538dbd6, caller:0x8d4de2bc1a566b266bd4b387f62c21e15474d12a,target:0x52d69c67536f55efefe02941868e5e762538dbd6 is_static:false, transfer:Transfer(294000000000000000), input_size:4
After the first bid, the victim refunds the previously tracked bidder. The trace then shows the attacker helper querying the victim's minimum-bid getter and reentering with 0.014700000000000001 ETH, while the victim is still sending the larger 0.294 ETH refund back to the same helper address:
Origin: seed transaction trace
SM Address: 0x52d69c67536f55efefe02941868e5e762538dbd6, caller:0x8d4de2bc1a566b266bd4b387f62c21e15474d12a,target:0x52d69c67536f55efefe02941868e5e762538dbd6 is_static:true, transfer:Transfer(0), input_size:4
SM Address: 0x52d69c67536f55efefe02941868e5e762538dbd6, caller:0x8d4de2bc1a566b266bd4b387f62c21e15474d12a,target:0x52d69c67536f55efefe02941868e5e762538dbd6 is_static:false, transfer:Transfer(14700000000000001), input_size:4
SM Address: 0x8d4de2bc1a566b266bd4b387f62c21e15474d12a, caller:0x52d69c67536f55efefe02941868e5e762538dbd6,target:0x8d4de2bc1a566b266bd4b387f62c21e15474d12a is_static:false, transfer:Transfer(294000000000000000), input_size:0
This is the decisive invariant break. The victim lets the same bidder address replace a larger tracked bid with a much smaller one while collecting the larger refund first. Because the helper's callback is attacker-controlled, the sequence repeats recursively. The trace records many repetitions of the same pattern, and the final storage transition confirms the tracked bidder changed from the prior bidder to the attacker helper:
Origin: seed transaction trace
@ 1160: 0x0000000000000000000000001298ef04e9e878dae51e605816ce3e6a99ad9b80 → 0x0000000000000000000000008d4de2bc1a566b266bd4b387f62c21e15474d12a
The balance-diff artifact quantifies the effect. The victim lost 11160974999999999960 wei, the adversary EOA gained 11129458888958904998 wei net, and the helper finished at zero because it swept the drained ETH back to the EOA:
Origin: seed transaction balance diff
{
"address": "0x52d69c67536f55efefe02941868e5e762538dbd6",
"delta_wei": "-11160974999999999960"
}
{
"address": "0x145766a51ae96e69810fe76f6f68fd0e95675a0b",
"delta_wei": "11129458888958904998"
}
The adversary first deployed helper contract 0x8d4de2bc1a566b266bd4b387f62c21e15474d12a in transaction 0x0b4a900733e8c33d562d0b9f2e6bd39317508095bab00fc83023c5951faae257. The helper is important because an EOA alone cannot execute code during the refund callback. The seed transaction then funded that helper with 0.6 ETH and used it as both the bidder and the refund recipient.
The helper's execution flow is straightforward. It places an initial large bid to become the tracked bidder, then places a second smaller bid to trigger the refund path back into itself. Inside receive(), it reads the victim's current next-minimum bid using selector 0x97d54cf7, increments a loop counter, and calls makeBid() again with the smaller amount. Each recursive iteration preserves the helper as the bidder while pulling another larger refund out of the victim.
The transaction ends by sweeping the helper's ETH back to the adversary EOA. The final trace line shows the helper transferring 11760974999999999960 wei to 0x145766a51ae96e69810fe76f6f68fd0e95675a0b, which is consistent with the helper serving only as an execution vehicle and the EOA realizing the profit.
The measurable victim loss in the seed transaction was 11.160974999999999960 ETH, encoded as 11160974999999999960 wei. After paying 0.031516111041094962 ETH in gas, the adversary EOA still realized 11.129458888958904998 ETH in net profit. The attack is therefore both technically valid and economically decisive.
The affected party is the victim contract itself and, indirectly, anyone relying on its ETH pool and active-bid accounting. Because the flaw is in the public bidding path and requires no privileged setup beyond deploying a helper contract, the incident fits the ACT model.
0x0eb8f8d148508e752d9643ccf49ac4cb0c21cbad346b5bbcf2d06974d31bd5c40x52d69c67536f55efefe02941868e5e762538dbd60x145766a51ae96e69810fe76f6f68fd0e95675a0b0x8d4de2bc1a566b266bd4b387f62c21e15474d12a0x1298ef04e9e878dae51e605816ce3e6a99ad9b80/workspace/session/artifacts/collector/seed/1/0x0eb8f8d148508e752d9643ccf49ac4cb0c21cbad346b5bbcf2d06974d31bd5c4/metadata.json/workspace/session/artifacts/collector/seed/1/0x0eb8f8d148508e752d9643ccf49ac4cb0c21cbad346b5bbcf2d06974d31bd5c4/trace.cast.log/workspace/session/artifacts/collector/seed/1/0x0eb8f8d148508e752d9643ccf49ac4cb0c21cbad346b5bbcf2d06974d31bd5c4/balance_diff.jsonhttps://ethervm.io/decompile/0x52d69c67536f55efefe02941868e5e762538dbd6https://etherscan.io/tx/0xaae44586bdbde1179c990aa64a1b0f2d20044cabf108591f35ea15cc1cdff45c