Reproduced Exploit
Superform: A depositor who sets receiver != controller can never redeem: shares mint to the receiver
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: 63077-controller-and-receiver-cannot-redeem-shares-after-depositin. The historical source/toolchain is unavailable; this entry is documentation only and claims no executable Forge PoC.
Vulnerability classes: vuln/locked-funds · vuln/unfair-mint
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 depositor who sets receiver != controller can never redeem: shares mint to the receiver while the redeem cost-basis state is recorded under the controller, so receiver-redeem reverts INSUFFICIENT_SHARES (empty state) and controller-redeem reverts (no shares) — 100 USDC is permanently locked in the vault.
// ── VERBATIM audited call-site: cost-basis state credited to the
// controller (msg.sender), shares minted to `receiver`. ──────────────
strategy.handleOperation(msg.sender, receiver, assets, shares, ISuperVaultStrategy.Operation.Deposit); // @> state keyed to controller(msg.sender), not the share receiver
_mint(receiver, shares);
}
Why it's exploitable here#
A depositor who sets receiver != controller can never redeem: shares mint to the receiver while the redeem cost-basis state is recorded under the controller, so receiver-redeem reverts INSUFFICIENT_SHARES (empty state) and controller-redeem reverts (no shares) — 100 USDC is permanently locked in the vault.
Attack path#
Marked-line walkthrough (Playground)#
The EVM Playground pins each step to the exact executed source line in 0xce01759b82…:
- L225 — Deposit state keyed to controller: Root cause: deposit records redeem state under
msg.sender(controller) while shares mint to a differentreceiver, splitting the two. - L231 — Redeem takes controller and owner:
redeemacceptscontrollerandownerseparately, but the deposit recorded state under only one of them. - L232 — Require owner to hold shares: Reverts
NoSharesToRedeemunlessownerholds the shares — the controller-redeem path dies here. - L238 — Would pay assets one-for-one: Sets
assets = sharesfor a 1:1 payout — but execution never reaches it once redeem reverts. - L249 — Share token name constant: Setup: the vault share token's constant
name. - L253 — Share balance ledger: Setup: per-holder share
balanceOf— empty for the controller, so its redeem reverts. - L256 — Immutable strategy pointer: Setup: immutable
strategyholding the deposit/redeem state that was keyed to the wrong address.
PoC#
Registry (Foundry, local deploy — verbatim vulnerable source + harm-asserting test + negative control):
cd 63077-controller-and-receiver-cannot-redeem-shares-after-depositin_exp
forge test -vvv
The browser Playground replays the same synthetic opcode-for-opcode and measures the harm: A depositor who sets receiver != controller can never redeem: shares mint to the receiver while the redeem cost-basis state is recorded unde. 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: 63077-controller-and-receiver-cannot-redeem-shares-after-depositin.
- Upstream DeFiHackLabs PoC directory: src/test.
Alerts & third-party analyses
- DeFiHackLabs incident explorer: search "Superform: A depositor who sets receiver != controller can never redeem: shares mint to the receiver".
- 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.