Reproduced Exploit
Remora — `buyTokenOCP` signatures reusable forever (missing nonce)
1. buyTokenOCP verifies an EIP-712-style BuyToken(investor, token, amount) signature and skips on-chain payment. 2. The hash omits a nonce and nothing marks the digest as used. 3. The same signature is submitted N times → N free token purchases. 4. HARM in the PoC: one signature buys 5 inventory to…
Chain
Other
Category
signature
Date
Oct 2025
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: 63777-signatures-on-tokenbank-and-allowlist-can-be-reused-in-perpe. Standalone Foundry PoC and full write-up: 63777-signatures-on-tokenbank-and-allowlist-can-be-reused-in-perpe_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/signature/missing-nonce · vuln/auth/replay · vuln/logic/free-mint
Reproduction: self-contained Foundry PoC with only
forge-std. Full trace: output.txt. PoC: test/63777-signatures-on-tokenbank-and-allowlist-can-be-reused-in-perpe_exp.sol.
AuditVault taxonomy: lang/solidity · platform/cyfrin · has/github · has/poc · severity/high · sector/perpetuals · sector/stable · genome: missing-modifier · role-bypass · permit-fork-replay
Key info#
| Impact | HIGH — a single off-chain-payment signature can be replayed indefinitely to mint free tokens via buyTokenOCP |
| Protocol | Remora Dynamic Tokens |
| Vulnerable code | TokenBank.verifySignature — struct hash is (investor, token, amount) with no nonce / used-digest map |
| Bug class | Signature replay (missing nonce) |
| Finding | Cyfrin — Remora Dynamic Tokens v2.1, 2025-10-22 · #63777 · reporter 0xStalin |
| Report | Cyfrin Remora report |
| Source | AuditVault |
| Status | Fixed at commit 4f73c1d. Local synthetic PoC. |
| Compiler | ^0.8.24 (PoC) |
TL;DR#
buyTokenOCPverifies an EIP-712-styleBuyToken(investor, token, amount)signature and skips on-chain payment.- The hash omits a nonce and nothing marks the digest as used.
- The same signature is submitted N times → N free token purchases.
- HARM in the PoC: one signature buys 5 inventory tokens.
The vulnerable code#
bytes32 structHash = keccak256(
abi.encode(BUY_TOKEN_TYPEHASH, investor, token, amount)
); // @> VULN: no nonce
Fix: include and bump a per-investor nonce (or store used digests).
Root cause#
Off-chain-payment authorization is a pure function of static fields. Without a one-time nonce, each signature is a free mint coupon of unlimited use.
Preconditions#
- A valid authorized-signer signature for
(investor, token, amount). - Sufficient TokenBank inventory.
Attack walkthrough#
- Obtain one signed
BuyTokenfor 1 unit. - Call
buyTokenOCPwith that signature five times. - Receive five free tokens; inventory is drained.
Diagrams#
Impact#
Unbounded free mint of central tokens for the cost of a single off-chain signature. Same missing-nonce pattern on AllowList lets removed admins re-add themselves.
Sources#
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 63777-signatures-on-tokenbank-and-allowlist-can-be-reused-in-perpe_exp (evm-hack-registry mirror).
- AuditVault finding: 63777-signatures-on-tokenbank-and-allowlist-can-be-reused-in-perpe.
Alerts & third-party analyses
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.