Reproduced Exploit
Tenbin: One delegated redeem order replayed 3x drains 3000e18 collateral to the attacker (order.re
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: 64973-redeem-nonce-mis-tracked-enables-replay-spearbit-none-tenbin. The historical source/toolchain is unavailable; this entry is documentation only and claims no executable Forge PoC.
Vulnerability classes: vuln/theft · vuln/locked-funds
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#
One delegated redeem order replayed 3x drains 3000e18 collateral to the attacker (order.recipient) and burns the victim/payer's assets 3x, because redeem records the nonce under the signer's slot while validating the payer's, so the payer nonce is never consumed.
// ── verbatim vulnerable redeem (Controller.sol L306-307) ──────────────────
function redeem(Order calldata order, Signature calldata signature) external onlyRole(MINTER_ROLE) {
(address signer,) = verifyOrder(order, signature); // checks payer nonce
nonces[signer][order.nonce] = true; // @> records SIGNER's nonce, not the payer's — the payer nonce checked above is never consumed, so a delegated order replays
IERC20(order.collateral_token).safeTransferFrom(manager, order.recipient, order.collateral_amount);
AssetToken(asset).burn(order.payer, order.asset_amount);
Why it's exploitable here#
One delegated redeem order replayed 3x drains 3000e18 collateral to the attacker (order.recipient) and burns the victim/payer's assets 3x, because redeem records the nonce under the signer's slot while validating the payer's, so the payer nonce is never consumed.
Attack path#
Marked-line walkthrough (Playground)#
The EVM Playground pins each step to the exact executed source line in 0xbd4fd5a3ce…:
- L42 — Token decimals constant: Setup: declares the token's 18 decimals.
- L160 — Verify an account's nonce: Setup: checks that
nonceis unused for a given account — called on the payer, whose slot is what must actually be consumed. - L167 — Verify redeem order signature: Setup: validates the order signature and recovers the delegated
signerwho authorized it. - L168 — Public verify visibility: Setup:
verifyOrderis publicly callable — this keyword is part of its signature. - L170 — Return recovered signer: Setup: hands back the recovered
signeraddress and a validity flag to the caller. - L177 — Redeem entry, minter-gated: Setup:
redeemburns the payer's assets and pays collateral toorder.recipient, guarded byMINTER_ROLE. - L179 — Nonce marked under wrong account: Records the nonce under the recovered
signer's slot, but validation checks the payer's slot, so the payer nonce is never consumed and the order replays.
PoC#
Registry (Foundry, local deploy — verbatim vulnerable source + harm-asserting test + negative control):
cd 64973-redeem-nonce-mis-tracked-enables-replay-spearbit-none-tenbin_exp
forge test -vvv
The browser Playground replays the same synthetic opcode-for-opcode and measures the harm: One delegated redeem order replayed 3x drains 3000e18 collateral to the attacker (order.recipient) and burns the victim/payer's assets 3x, b. Both gates are green (registry forge test PASS + Playground _verify-poc VERDICT: PASS).
Sources & further analysis#
Reproductions & code
- No executable Forge reproduction is claimed; the historical source/toolchain was unavailable for this finding.
- AuditVault finding: 64973-redeem-nonce-mis-tracked-enables-replay-spearbit-none-tenbin.
- Upstream DeFiHackLabs PoC directory: src/test.
Alerts & third-party analyses
- DeFiHackLabs incident explorer: [search "Tenbin: One delegated redeem order replayed 3x drains 3000e18 collateral to the attacker (order.re"](https://defihacklabs.io/explorer/index.html?q=Tenbin%3A%20One%20delegated%20redeem%20order%20replayed%203x%20drains%203000e18%20collateral%20to%20the%20attacker%20(order.re).
- Web3Sec X hacked database: search.
- Rekt leaderboard: [search](https://rekt.news/?s=Tenbin%3A%20One%20delegated%20redeem%20order%20replayed%203x%20drains%203000e18%20collateral%20to%20the%20attacker%20(order.re).
- Solodit incident search: [search](https://solodit.xyz/issues?search=Tenbin%3A%20One%20delegated%20redeem%20order%20replayed%203x%20drains%203000e18%20collateral%20to%20the%20attacker%20(order.re).
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.