Reproduced Exploit
Biconomy Composability — [C-01] Missing DelegateCall check
1. executeComposableDelegateCall is meant only via smart-account CALLTYPE_DELEGATECALL. 2. There is no check that address(this) differs from the module’s immutable deployment address. 3. Anyone can call the function directly on the module and run composed calls (e.g. writeStorage). 4. Shared storag…
Chain
Other
Category
access-control
Date
Mar 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: 63148-c-01-missing-delegatecall-check-pashov-audit-group-none-bico. Standalone Foundry PoC and full write-up: 63148-c-01-missing-delegatecall-check-pashov-audit-group-none-bico_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/access-control/missing-guard · ownership-takeover · missing-modifier
Reproduction: a self-contained Foundry PoC that compiles & runs in an isolated project with only
forge-std— no fork, no RPC, noanvil_state. Full trace: output.txt. PoC: test/63148-c-01-missing-delegatecall-check-pashov-audit-group-none-bico_exp.sol.
AuditVault taxonomy: severity/high · sector/account · sector/staking · platform/pashov · missing-modifier · ownership-takeover · cross-protocol · access-roles · blast-radius/cross-protocol
Key info#
| Impact | HIGH — direct call runs unrestricted composed executions / storage writes as the module |
| Protocol | Biconomy Composability — ComposableExecutionModule |
| Vulnerable code | executeComposableDelegateCall lacks require(THIS_ADDRESS != address(this)) |
| Bug class | Missing delegatecall-only guard on module entrypoint |
| Finding | Pashov Audit Group · BiconomyComposability 2025-03-22 · #63148 |
| Report | Pashov review |
| Source | AuditVault |
| Status | Audit finding. Reproduced as a standalone local PoC. |
| Compiler | ^0.8.24 (PoC) |
TL;DR#
executeComposableDelegateCallis meant only via smart-accountCALLTYPE_DELEGATECALL.- There is no check that
address(this)differs from the module’s immutable deployment address. - Anyone can call the function directly on the module and run composed calls (e.g.
writeStorage). - Shared storage for account namespaces can be corrupted; combined with executor paths this enables unrestricted account operations.
The vulnerable code#
function executeComposableDelegateCall(ComposableExecution[] calldata executions) external {
// FIX: require(THIS_ADDRESS != address(this), "NotAllowed");
_executeComposable(executions); // @> VULN: missing delegatecall-only guard
}
Root cause#
The function relies on a documentation convention (“expected to be called via delegatecall”) instead of an on-chain identity check. Direct CALL keeps address(this) == module, so module-privileged composed logic runs for arbitrary callers.
Preconditions#
- Module deployed and (in the full system) installed on target smart accounts / sharing Storage.
- Attacker can craft
ComposableExecution[]payloads (e.g.writeStorage).
Attack walkthrough#
- Read target storage slot under account namespace (initially 0).
- Build a composed execution targeting
Storage.writeStorage(slot, 420, account). - Call
executeComposableDelegateCalldirectly on the module (no account, no delegatecall). - Slot is overwritten to 420 under the module’s write path.
Diagrams#
Impact#
Unauthorized storage manipulation and, via executeFromExecutor paths in the full system, unrestricted operations on smart accounts that installed the module.
Sources#
- AuditVault finding #63148
- Pashov BiconomyComposability security review 2025-03-22
- Reduced source:
ComposableExecutionModule.executeComposableDelegateCall(Pashov report)
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 63148-c-01-missing-delegatecall-check-pashov-audit-group-none-bico_exp (evm-hack-registry mirror).
- AuditVault finding: 63148-c-01-missing-delegatecall-check-pashov-audit-group-none-bico.
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.