Reproduced Exploit
Barter DAO: A one-time signed order authorizing a single 100-makerToken fill is replayed after the mak
Chain
Other
Category
untagged
Date
Jan 1970
Source
AuditVault
EVM Playground
Source-level debugger — step opcodes and Solidity in sync
The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.
Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 63501-replay-attack-via-balance-based-nonce-mixbytes-none-barter-d. Standalone Foundry PoC and full write-up: 63501-replay-attack-via-balance-based-nonce-mixbytes-none-barter-d_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/theft · vuln/access-control
Reproduction: a faithful minimal reproduction of the vulnerable finding — the vulnerable function is reproduced verbatim (marked
@>) with faithful minimal doubles; local deploy, no fork.
Root cause#
A one-time signed order authorizing a single 100-makerToken fill is replayed after the maker's balance recovers, filling it twice and draining 200 STOLEN-MAKER to the attacker EOA from one signature.
signed[orderHash] = true;
}
function approveToken(MiniToken token, address spender, uint256 amount) external {
require(msg.sender == owner, "not owner");
token.approve(spender, amount);
Why it's exploitable here#
A one-time signed order authorizing a single 100-makerToken fill is replayed after the maker's balance recovers, filling it twice and draining 200 STOLEN-MAKER to the attacker EOA from one signature.
Attack path#
Marked-line walkthrough (Playground)#
The EVM Playground pins each step to the exact executed source line in 0xbd4fd5a3ce…:
- L105 — EIP-1271 magic value: Setup: the EIP-1271
isValidSignaturemagic return value used to validate the maker's signed order. - L107 — Signed-order registry mapping: Setup: maps an order hash to whether the maker signed it — tracking validity, but not one-time consumption.
- L109 — Signer contract constructor: Setup: initializes the maker/signer contract.
- L115 — Mark order as signed: Records an order hash as authorized; this flag stays true, so the same signature keeps validating on repeat fills.
- L118 — Re-approve enables replay: Root cause: fill eligibility is gated by maker balance/allowance as an implicit nonce, so re-approving here lets one signed order fill twice.
- L166 — Consumed-order guard mapping: Declares a per-order
consumedreplay guard, but the fill path leans on maker balance instead, leaving the order replayable. - L171 — Hash the order: Computes the order's hash used to look up its signed/consumed status when filling.
PoC#
Registry (Foundry, local deploy — verbatim vulnerable source + harm-asserting test + negative control):
cd 63501-replay-attack-via-balance-based-nonce-mixbytes-none-barter-d_exp
forge test -vvv
The browser Playground replays the same synthetic opcode-for-opcode and measures the harm: A one-time signed order authorizing a single 100-makerToken fill is replayed after the maker's balance recovers, filling it twice and draini. Both gates are green (registry forge test PASS + Playground _verify-poc VERDICT: PASS).
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 63501-replay-attack-via-balance-based-nonce-mixbytes-none-barter-d_exp (evm-hack-registry mirror).
- AuditVault finding: 63501-replay-attack-via-balance-based-nonce-mixbytes-none-barter-d.
- Upstream DeFiHackLabs PoC directory: src/test.
Alerts & third-party analyses
- DeFiHackLabs incident explorer: search "Barter DAO: A one-time signed order authorizing a single 100-makerToken fill is replayed after the mak".
- Web3Sec X hacked database: search.
- Rekt leaderboard: search.
- Solodit incident search: search.
These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.