Reproduced Exploit

Centrifuge v3.1 — pool managers steal other pools pending deposits

Spoke.requestCallback uses current requestManager without binding to the manager that created the request

Oct 2025Otheruntagged2 min read

Chain

Other

Category

untagged

Date

Oct 2025

Source

AuditVault

EVM Playground

Source-level debugger — step opcodes and Solidity in sync

evm-hack-analyzer

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.

Loading fork state…

Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 64195-h-1-pool-managers-can-steal-all-other-pools-pending-deposits. Standalone Foundry PoC and full write-up: 64195-h-1-pool-managers-can-steal-all-other-pools-pending-deposits_exp in the evm-hack-registry mirror.


Reproduction: self-contained Foundry PoC (forge-std only) — no fork. Full trace: output.txt.

AuditVault taxonomy: lang/solidity · platform/sherlock · severity/high · genome: centralization · direct-drain · bridge-sender-auth


Key info#

ImpactHIGH — All pending deposits in globalEscrow transferable to attacker pool escrow via requestManager swap
ProtocolCentrifuge Protocol v3.1
Bug classSpoke.requestCallback uses current requestManager without binding to the manager that created the request
FindingSherlock 0x52 et al. (H-1) · #64195
Reporthttps://github.com/sherlock-audit/2025-10-centrifuge-protocol-v3-1-audit-judging
SourceAuditVault
StatusAudit finding — reproduced as a standalone local synthetic
Compiler^0.8.24 (PoC)

TL;DR#

Spoke.requestCallback uses current requestManager without binding to the manager that created the request

HARM: All pending deposits in globalEscrow transferable to attacker pool escrow via requestManager swap


Root cause#

Spoke.requestCallback uses current requestManager without binding to the manager that created the request

Preconditions#

Protocol-specific setup as described in the original finding (roles / managers / pending state in place).

Attack walkthrough#

See the synthetic test/64195-h-1-pool-managers-can-steal-all-other-pools-pending-deposits.sol and the Playground story beats. The @> VULN marker sits on the blamed executable line.

Diagrams#

sequenceDiagram participant M as Malicious manager participant S as Spoke participant H as Hub participant A as AsyncRequestManager participant G as GlobalEscrow H->>S: setRequestManager malicious M->>S: request fraudulent deposit H->>S: setRequestManager Async H->>S: requestCallback approvedDeposits S->>A: callback current manager A->>G: authTransferTo attacker escrow

Impact#

All pending deposits in globalEscrow transferable to attacker pool escrow via requestManager swap

Sources#


Sources & further analysis#

Reproductions & code

Alerts & third-party analyses

  • 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.