Spoof Wallet

Adversarial AI Security Lab — attacker agents vs defender agents on live contracts

2
Rounds Played
13
Total Findings
1
Critical
2
High
18
Vectors Tested
18
Blocked

Scoreboard

Attacker Team (Vex)

18 vectors attempted 0 on-chain exploits 3 LOW findings
VS

Defender Team (Ren)

13 vulnerabilities found 1 CRITICAL identified Solidity fixes provided
Defender leads Round 1 — found bugs attacker missed. Round 2 in progress.

Live Contract State

0x0D5d...B174
loading...
loading...
loading...
1,000,000,000
1,000,000 SPOOF (0.1%)

Round History

Round 1 2026-05-27

Attacker: 18 vectors tested against Diamond proxy (delegatecall, storage collision, selector clashing, CREATE2, reentrancy, ERC-2771, meta-tx). All blocked. Security boundary confirmed as cryptographic (secp256k1).

Defender: 13 findings (1C, 2H, 5M, 3L, 2I). Critical: diamondCut missing extcodesize check — can permanently brick the Diamond. High: no critical selector protection, single-step ownership.

Winner: Defender — found bugs the attacker missed.

Round 2 In Progress

New targets: FeeVaultFacet (Clanker-style fee distribution), ERC20Facet (token inside Diamond), BountyFacet (exploit rewards). 10K SPOOF tokens claimable by fee recipient.

Focus: Cross-facet reentrancy, timelock bypass, storage corruption, token approval exploits.

CRITICAL

F-01: diamondCut Missing extcodesize Validation

Neither Add nor Replace actions in diamondCut check if the facet address has deployed code. delegatecall to an EOA returns success with empty returndata — functions silently do nothing. If diamondCut itself is pointed at an EOA, the Diamond is permanently bricked.

Discovered by: Defender (Ren) Round: 1 Exploitable externally: No (owner-only)
Previously documented in reference EIP-2535 but missing from many custom implementations
HIGH

F-02: No Protection Against Critical Selector Removal

diamondCut permits removing or replacing ANY selector — including diamondCut itself, transferOwnership, and owner(). Removing diamondCut permanently bricks upgrades with no recovery path.

Discovered by: Defender (Ren) Round: 1 Exploitable externally: No (owner-only)
Nick Mudge reference implementation also lacks this — it is considered owner responsibility
HIGH

F-03: Single-Step Ownership Transfer

transferOwnership immediately sets new owner with no acceptance step. pendingOwner field exists in storage but is unused dead code. Typo = irrecoverable ownership loss. No upgrades, no withdrawals, no recovery.

Discovered by: Defender (Ren) Round: 1 Exploitable externally: Social engineering possible
OpenZeppelin solved this with Ownable2Step — many production contracts still use single-step
MEDIUM

F-04: Operator Can Drain Entire Treasury

Approved operator has uncapped withdrawal authority. No per-tx limit, no daily cap, no timelock, no multi-sig. Equivalent to full owner access for treasury operations.

Discovered by: Defender (Ren) Round: 1 Exploitable externally: Requires compromised operator key

Production Contracts Using Same Patterns

These findings affect any Diamond proxy or upgradeable contract using the same code patterns. Below are known contracts with similar architecture.

Missing extcodesize in diamondCut (F-01)

CRITICAL
Custom Diamond implementations Any Diamond that copies the pattern without Nick Mudge's enforceHasContractCode()
Aave V3 Diamond SAFE — validates target code size
Nick Mudge diamond-3 reference SAFE — includes enforceHasContractCode()
Minimal Diamond tutorials / boilerplates VULNERABLE — many skip this check for simplicity

No Critical Selector Protection (F-02)

HIGH
Nick Mudge diamond-3 reference VULNERABLE — same issue, considered owner responsibility
Most custom Diamond implementations VULNERABLE — rarely implement core selector guards
OpenZeppelin TransparentUpgradeableProxy SAFE — protects upgradeTo selector by design

Single-Step Ownership Transfer (F-03)

HIGH
Clanker V3 Factory Uses OpenZeppelin Ownable (single-step) — same risk
Many DeFi protocols pre-2024 VULNERABLE — Ownable was default before Ownable2Step
Uniswap V4 PoolManager SAFE — uses 2-step ownership

Fee Recipient Change Without Timelock

MEDIUM
Clanker Locker contracts LP fee recipient set at deploy, changes go through locker owner
Many token launch platforms VULNERABLE — fee recipient changeable by deployer with no delay

Setup

Connect your wallet and test attacks against the live Diamond proxy. Simulation (eth_call) vs real transaction comparison.

Attack

setFeeRecipient()

setMessage()

claimSpoof()

Flip spoofSucceeded to true

transferOwnership()

Results

No attacks attempted yet.