Skip to content

Contract Analysis

DISCLAIMER // NFA // DYOR

This analysis is based on observations of the contract behavior. We are not smart contract security experts. This document aims to explain what the contract appears to do based on the code. It should not be considered a comprehensive security audit or financial advice. Always verify critical information independently and consult with blockchain security professionals for important decisions.

⊙ generated by robots | curated by humans

Analysis Date: 2026-08-11


Metadata

Primary Contract

PROPERTY VALUE
Contract Address 0xb276f62d...1eac1c (etherscan)
Network Ethereum Mainnet
Snapshot Block 25733839
Contract Type Standalone
Deployment Date 2026-07-16 17:42 UTC
Deployment Block 25546793
Contract Creator 0x019817aD...13E8Cb (etherscan)
Creation TX 0xa711a902...fd3c78 (tx)
Compiler Version Solidity v0.8.30+commit.73712a01, optimizer enabled (runs = 1), EVM version prague
Runtime Size 21,425 bytes (3,151 under the EIP-170 limit)
Total Functions 92 (57 view/pure, 35 state-changing, 12 payable)
External Contract Dependencies 7 (VRF coordinator, VRF service, rewards module, FWAToken, whitelist manager, payout splitter, and each listed ERC-721)
Upgrade Mechanism ☒ None — Not Upgradable
Verification Status ☑ Verified on Etherscan (Exact Match)
Audit Status ☒ No audit published at time of analysis
TYPE ADDRESS NOTES
Owner 0x019817aD...13E8Cb (etherscan) The deployer Externally Owned Account (EOA) itself. Solady Ownable. No multisig or timelock.
Payout Address 0x1C175b9F...373Bfe (etherscan) Splitter contract. Set 1 minute after deployment. Receives the non-token slice of protocol fees, currently zero.
Whitelist Manager 0x854352b2...5e17c3 (etherscan) FWAWhitelist contract. Can add or remove collections without being owner.
Rewards Module 0x6a1a1C0C...92fc78 (etherscan) FWARewards. Wired once via setRewards; cannot be replaced.
Token 0xa0Df17B5...20C845 (etherscan) FWAToken. Read from the rewards module, not set directly.
VRF Service 0xa084c33F...2E5D9f (etherscan) FWAVRFService. Immutable constructor argument. Collects the purchaser's randomness fee and funds the subscription.
Verifiable Random Function (VRF) Coordinator 0xd7f86b4b...20893a (etherscan) Chainlink VRFCoordinatorV2_5. Owner-replaceable while the pool is quiescent.
Superseded Pool 0x6596170e...8a6322 (etherscan) Earlier FWA deployed 2026-06-30, still on-chain with 8 active listings.

Executive Summary

FWA is the acquisition pool behind fwa.fun, a TokenWorks work. It is a randomized NFT marketplace in which the seller sets both the asking price and the odds, and the buyer does not choose what they are buying.

A depositor escrows one ERC-721 together with an amount of ETH they choose, called the backing. That backing does two jobs at once. It sets the listing's selection weight inversely — weight = 1e36 / backing, so a cheaply-backed listing is drawn far more often than a richly-backed one — and it funds an irrevocable standing bid to buy the NFT back. A purchaser pays a fee, receives one randomly selected listing via Chainlink VRF, and then chooses: keep the NFT, or take the depositor's ETH. The two outcomes are mutually exclusive and enforced by a single status transition, so a purchaser can never walk away with both.

The pricing mechanism is the load-bearing piece, and it reproduces independently. Because weight is inversely proportional to backing, the product weight · backing is approximately the same constant for every listing, and the pool's expected value collapses to the Harmonic Mean of all backings. We computed that mean independently from all 5,770 active listings and it reproduces the contract's internal figure to the wei: 0.079742869391249362 ETH at block 25733839. The purchaser pays that expected value plus a surcharge, currently 2.5%.

The intended audience is two-sided. Depositors are people holding NFTs they would sell at a known price, who earn an equal share of every acquisition fee while they wait. Purchasers are people willing to buy a random draw from that pool. As pure ETH arithmetic the purchaser side is negative — pay 1.025 × expected backing, and the ETH exit returns 90% of backing — so the acquisition side is subsidised by FWAToken emissions from a separate rewards module rather than by the pool itself.

The most important thing we verified is solvency. The contract's design claim is that every wei it holds is spoken for and that no listing's backing can be spent on another listing's obligations. We reconstructed all eight liability components from chain state — 5,770 active backings, 56 allocated backings, the uncredited dividend accumulator, 348 addresses with credited fee balances, the top-listing pot, and three counters that were all zero — and compared the total against the contract's ETH balance. The surplus is 157,011 wei, or 1.57 × 10⁻¹³ ETH: rounding dust from an accumulator that deliberately floors credits and ceils checkpoints so it can never over-credit. At the snapshot block the contract is fully backed.

The significant trust assumption is governance, not accounting. The owner is a single externally-owned account with no multisig or timelock, and the fee parameters it controls are not symmetrically bounded. A depositor's principal is protected by a hard-coded 5% cap on the settlement fee, so the settlement cut cannot exceed 5% of backing. A depositor's yield has no such protection: ownerAcquisitionFeeBps is capped only at 100%, so the owner can redirect the entire acquisition fee stream to the protocol at any moment the pool is idle, without warning. That same key holds 1,088 ETH and owns the rewards module, the VRF service, and the VRF subscription.

The public repository at token-works/fwa-relaunch is not the deployed contract. It is a single-commit snapshot from 2026-07-08; the contract deployed eight days later is a substantially refactored version with the Uniswap V4 integration removed and VRF fee logic moved into an external service. This analysis reads the Etherscan-verified source, which is what actually runs.


Architecture

graph TB
    subgraph Actors
        DEP[Depositor]
        PUR[Purchaser]
        KEEP[Anyone / keeper]
        OWN[Owner EOA]
    end

    subgraph Core["FWA — 0xb276f62d...1eac1c"]
        LIST["Listing store<br/>149,854 ids, 5,770 active"]
        TREE["Segment tree<br/>depth 32, weighted selection"]
        STAGE["Staging FIFO<br/>anti-steering queue"]
        SEQ["Sequence ledger<br/>ordered settlement"]
        ACC["Dividend accumulator<br/>flat 1 share per listing"]
        TOP["Top-listing slot + pot"]
    end

    subgraph External
        VRFS["FWAVRFService<br/>0xa084c33f...2e5d9f"]
        COORD["Chainlink VRFCoordinatorV2_5<br/>0xd7f86b4b...20893a"]
        REW["FWARewards<br/>0x6a1a1c0c...92fc78"]
        TOK["FWAToken<br/>0xa0df17b5...20c845"]
        WL["FWAWhitelist<br/>0x854352b2...5e17c3"]
        SPL["Splitter<br/>0x1c175b9f...373bfe"]
        NFT["Listed ERC-721 collections<br/>47 active"]
    end

    DEP -->|listNFT + backing ETH| LIST
    LIST --> STAGE
    STAGE -->|activate| TREE
    PUR -->|acquire + fee| SEQ
    SEQ -->|prepareRequests + fee| VRFS
    VRFS -->|fund subscription| COORD
    SEQ -->|requestRandomWords| COORD
    COORD -->|rawFulfillRandomWords| SEQ
    SEQ -->|select slot| TREE
    SEQ --> ACC
    SEQ --> TOP
    KEEP -->|processAcquisitions| SEQ
    PUR -->|keepNFT / acceptDepositorBid| LIST
    LIST -->|transferFrom| NFT
    SEQ -->|registerAcquisition / settleAcquisition| REW
    REW -->|buyFor| TOK
    ACC -->|payoutFees| TOK
    ACC -->|payoutFees| SPL
    OWN -->|setUint / setBool / setAddr| Core
    OWN --> WL
    WL -->|setCollectionsWhitelisted| Core

    style LIST fill:#e8f0ff
    style TREE fill:#e8f0ff
    style OWN fill:#ffe1e1
    style COORD fill:#fff4e1

System Overview

The contract is a single-file, standalone pool with no proxy and no upgrade path. Its job is to hold NFTs and ETH, price a random draw against them correctly, and settle the result in a fixed order.

  • Escrows an ERC-721 and a depositor-chosen ETH backing as one listing, and keeps the two bound together until the listing resolves.
  • Prices an acquisition at the harmonic mean of every active listing's backing, times a surcharge, using a depth-32 segment tree that makes weighted selection an O(32) descent rather than a scan.
  • Requests randomness from Chainlink per acquisition and assigns each request a local sequence number at request time, so requests are concurrent but settlement is strictly ordered.
  • Binds every listing's backing to that listing's own standing bid, which is the design's stated basis for solvency. We reconciled it at one block rather than proving it holds for all states.
  • Blocks withdrawals and re-pricing whenever any acquisition is unresolved, because removing weight from the tree would steer a draw that has already been paid for.
  • Does not value the NFT. Backing is whatever the depositor typed. The contract prices the backing distribution, not the collection floor, and nothing on-chain checks that a listing's NFT is worth its backing.
  • Does not protect depositor yield. The acquisition fee split is an owner parameter with a 100% ceiling.
  • Does not hold a treasury of its own. Protocol fees accrue to a counter and are pushed out permissionlessly; at the snapshot that counter is zero and 100% of the flow is routed to the FWAToken buyback reserve.

Design Patterns Used

  • Inverse weighting: weight = INVERSE_WEIGHT_NUMERATOR / value with the numerator fixed at 1e36. The shared constant cancels between any two listings, so it sets precision only. Its consequence — weight · value ≈ 1e36 for every listing — is what makes the pool's expected value a harmonic mean and lets weightedBackingTotal double as a listing counter scaled by 1e36.
  • Segment Tree over a mapping: TREE_DEPTH = 32 gives capacity for 2³² concurrent listings without allocating them. Only touched nodes cost storage. Selection walks the tree comparing a target against cumulative left-subtree weight.
  • Slot recycling with a free list: removed listings release their tree slot onto a LIFO free list (freeSlotHead, nextFreeSlot), so slot indices stay dense. We observed 5,770 active listings occupying slots up to 9651.
  • Dividend Accumulator: fees are distributed by incrementing accFeePerEV rather than iterating depositors. Each listing carries a feeDebt checkpoint. Checkpoints are ceiled on entry and credits floored on exit, an asymmetry intended to keep Σ credited ≤ Σ collected and consistent with the positive residue we observed.
  • Commit-then-request sequencing: the local sequence number and the exact batch of staged listings to activate are both committed before the external VRF call, so a coordinator revert rolls back both.
  • Staging FIFO as an anti-steering boundary: deposits made while an acquisition is unresolved do not enter the selection pool. They queue in a doubly-linked list and are reserved to a specific sequence, so no already-issued request can observe a listing that did not exist when it was priced.
  • Pull payments throughout: earnings, acquisition refunds, and protocol fees all accrue to counters and are withdrawn by their owner, rather than pushed during settlement.
  • Best-effort NFT delivery with a recovery path: a collection that reverts on transfer cannot block the ETH legs; the NFT is recorded against stuckNFTRecipient for a later pull.
  • Generic config dispatchers: the per-knob setters were collapsed into setUint / setBool / setAddr, together accepting 25 keys drawn from the 28 FWAConfigKeys constants, explicitly to fit under EIP-170.

Access Control

Roles & Permissions

ROLE ASSIGNED BY REVOKABLE CALL COUNT
Owner Constructor (_initializeOwner(msg.sender)) Yes — transferOwnership or renounceOwnership Unlimited
Whitelist Manager Owner via setAddr(WHITELIST_MANAGER) Yes — set to zero address Unlimited
VRF Service Constructor, immutable No Unlimited (only configureVrfRequest)
VRF Coordinator Constructor; owner-replaceable via setAddr(VRF_COORDINATOR) Yes — while quiescent Unlimited (only rawFulfillRandomWords)
Depositor Per listing, by calling listNFT N/A Per listing
Purchaser Per acquisition, by VRF allocation N/A Per listing
Anyone Permissionless N/A Unlimited

Permission Matrix

FUNCTION OWNER WL MANAGER DEPOSITOR PURCHASER ANYONE
listNFT ☑ ☑ ☑ ☑ ☑
acquire / acquireBatch ☑ ☑ ☑ ☑ ☑
withdrawListing ☒ ☒ ☑ own ☒ ☒
updateBacking ☒ ☒ ☑ own ☒ ☒
claimTopSpot ☒ ☒ ☑ own ☒ ☒
claimListingFees ☒ ☒ ☑ own ☒ ☒
keepNFT ☒ ☒ ☒ ☑ own ☒
acceptDepositorBid ☒ ☒ ☒ ☑ own ☒
acceptBidAsTokens ☒ ☒ ☒ ☑ own ☒
relistNFT ☒ ☒ ☒ ☑ own ☒
depositorReclaimBacking ☒ ☒ ☑ after window ☒ ☒
depositorReclaimNFT ☒ ☒ ☑ after window ☒ ☒
finalizeUnsettled ☑ after 7 days ☑ after 7 days ☑ after 7 days ☑ after 7 days ☑ after 7 days
processAcquisitions ☑ ☑ ☑ ☑ ☑
activateListings ☑ ☑ ☑ ☑ ☑
payoutFees ☑ ☑ ☑ ☑ ☑
withdrawEarnings ☑ ☑ ☑ ☑ ☑
reconcileUnfulfilledVrfCount ☑ ☑ ☑ ☑ ☑
recoverStuckNFT ☒ ☒ ☑ if owed ☑ if owed ☒
setUint / setBool / setAddr ☑ ☒ ☒ ☒ ☒
setCollectionsWhitelisted ☑ ☑ ☒ ☒ ☒
setRewards ☑ once ☒ ☒ ☒ ☒
configureVrfRequest ☒ ☒ ☒ ☒ ☒ VRF service only

Time Locks & Delays

ACTION TIME LOCK CAN CANCEL PURPOSE
Any owner config change ☒ None — effective immediately N/A ☒ No delay; only a state gate (unsettledAcquisitionCount == 0)
Transfer ownership ☒ None for direct transferOwnership N/A ☒ Solady's two-step handover exists but is optional
Purchaser resolution ☑ 24 hours exclusive (settlementWindow) N/A ☑ Purchaser's exclusive choice period
Depositor resolution ☑ Available after 24 hours N/A ☑ Prevents an unresponsive purchaser locking the listing
Public finalization ☑ Available after 7 days (finalizeWindow) N/A ☑ Guarantees neither asset locks permanently
VRF word deadline ☑ 30 blocks (selectionTimeoutBlocks) N/A △ Late callbacks become refunds

Economic Model

Purchase Flow

flowchart TD
    A[Purchaser calls acquire] --> B{Checks}
    B -->|withdrawOnly / not enabled / empty pool| Z1[Revert]
    B -->|fee > maxAcquisitionFee| Z1
    B -->|pool value < minWeightedValue| Z1
    B -->|pass| C["Pay fee + VRF service fee<br/>excess refunded"]
    C --> D["Commit sequence N<br/>reserve staged batch"]
    D --> E[requestRandomWords]
    E --> F{Word arrives<br/>within 30 blocks?}
    F -->|No| G["Status TimedOut/Expired<br/>pool fee → pull refund<br/>VRF fee not refunded"]
    F -->|Yes| H[Cache word, status Ready]
    H --> I["processAcquisitions reaches<br/>sequence N in order"]
    I --> J{Live fee within<br/>slippage tolerance?}
    J -->|No| G
    J -->|Yes| K["Select slot via segment tree<br/>target = word mod totalWeight"]
    K --> L["Split fee:<br/>token slice → rewards<br/>1% → protocol<br/>1% → top pot<br/>rest → all active listings"]
    L --> M[Listing status Allocated]
    M --> N{Purchaser choice<br/>within 24h}
    N -->|keepNFT| O["NFT → purchaser<br/>99% of backing → depositor"]
    N -->|acceptDepositorBid| P["90% of backing → purchaser<br/>NFT → depositor<br/>10% retained → protocol"]
    N -->|acceptBidAsTokens| Q["90% of backing buys FWAToken<br/>→ purchaser, NFT → depositor"]
    N -->|relistNFT| R["Old depositor paid<br/>NFT re-listed by purchaser"]
    N -->|No choice| S["After 24h depositor picks<br/>after 7 days anyone finalizes"]

    style Z1 fill:#ffe1e1
    style G fill:#fff4e1

Fee Structure

Values are those in force at block 25733839, with the constructor default shown where the owner has changed it.

FEE RATE DEFAULT AT DEPLOY TAKEN FROM RECIPIENT
Acquisition surcharge (surchargeBps) 2.50% 10.00% Purchaser, over expected value The depositor pool, via the fee split below
VRF service fee ~0.00027 ETH median N/A Purchaser, on top of the pool fee FWAVRFService, funds the Chainlink subscription
Protocol acquisition cut (ownerAcquisitionFeeBps) 1.00% 1.00% Distributable fee, after the token slice accruedOwnerFees
Top-listing share (topListingShareBps) 1.00% 5.00% Distributable fee, after the protocol cut topListingPot, settles to the top holder
Depositor distribution Remainder Remainder Distributable fee All active listings, equally per listing
Protocol settlement cut (ownerSettlementFeeBps) 1.00% 1.00% Backing returned to depositor accruedOwnerFees
Settlement retention 10.00% 15.00% Backing, when the purchaser takes ETH Protocol (retainedToProtocol is true)
Protocol fee to token (protocolFeeToTokenBps) 100.00% 0.00% accruedOwnerFees at payout FWAToken buyback reserve

ownerSettlementFeeBps is bounded by a hard-coded MAX_OWNER_SETTLEMENT_FEE_BPS = 500, so the settlement cut cannot exceed 5% of backing. ownerAcquisitionFeeBps is bounded only by BPS, so the owner may take up to 100% of the acquisition fee stream. Principal is protected by code; yield is not. Separately, surchargeBps is deliberately uncapped — the source notes an expected-value surcharge above 100% is a meaningful setting.

Because protocolFeeToTokenBps was raised to 100% on 2026-08-06, payoutFees currently sends the entire accrued balance to the FWAToken contract and zero to the payout address.

Funding Sources & Sinks

Inflows are depositor backing (escrowed per listing), purchaser acquisition fees (escrowed until ordered settlement), and purchaser VRF fees (forwarded immediately to the service, never held). Outflows are backing returns, purchaser settlements, depositor earnings withdrawals, acquisition refunds, and protocol fee payouts.

Economic Invariants

The contract's central claim is that its ETH balance always covers every recorded obligation, because each listing's backing settles only that listing's own bid. We tested this independently at block 25733839 by reconstructing every liability from chain state rather than trusting any aggregate the contract reports.

COMPONENT WEI ETH
Active listing backing (5,770 listings) 1246219052679687862152 1246.219052680
Allocated listing backing (56 listings) 3788921919190696970 3.788921919
Uncredited fee accumulator (pendingFees) 70370386500834949333 70.370386501
Credited earnings (feeCredit, 348 addresses) 39895179239947149387 39.895179240
Top-listing pot 9365078075945921140 9.365078076
Acquisition fee escrow 0 0.000000000
Acquisition refund credit 0 0.000000000
Accrued protocol fees 0 0.000000000
Total obligations 1369638618415606578982 1369.638618416
Contract ETH balance 1369638618415606735993 1369.638618416
Surplus 157011 0.000000000000157011

The 157,011 wei surplus is rounding dust. _activateListing ceils a listing's feeDebt checkpoint and _pendingFees floors the credit, so the accumulator under-credits by sub-wei amounts per listing per distribution. On the paths we read, that asymmetry biases the residue in the contract's favour; we did not enumerate every arithmetic path, so this is directional rather than proven.

Three structural invariants also reproduce exactly:

  • feeShareTotal (5,770) equals activeListingCount (5,770), confirming each listing's fee share is a flat 1. This contradicts the Listing struct's own comment, which describes feeShare as √backing; the deployed code sets uint256 feeShare = 1. The square-root weighting still exists, but it lives in the separate FWARewards module as sqrtBackingTotal.
  • treeRootWeight() equals totalWeight (72,357,566,815,035,813,943,552), confirming the segment tree root agrees with the flat counter after 149,854 insertions and 144,084 removals.
  • Summing weight × value across all 5,770 active listings reproduces weightedBackingTotal exactly, and dividing by totalWeight yields 0.079742869391249362 ETH — the same figure as computing the harmonic mean of the 5,770 backings directly.

Pool Composition

At block 25733839 the pool holds 5,770 active listings across 47 collections from 213 distinct depositors. 2,124 addresses have deposited at some point.

METRIC VALUE
Backing, minimum 0.0500 ETH (equals minBacking)
Backing, median 0.0850 ETH
Backing, mean (arithmetic) 0.2160 ETH
Backing, harmonic mean (the acquisition price basis) 0.0797 ETH
Backing, maximum 300.0000 ETH
Top 1 depositor share of listings 8.6%
Top 10 depositor share of listings 58.5%

The gap between the arithmetic mean (0.2160 ETH) and the harmonic mean (0.0797 ETH) is the inverse weighting doing its work. A purchaser is not buying an average listing; they are overwhelmingly likely to draw a cheap one, and the price reflects that.

The largest collection in the pool by listing count is Ten Thousand Tokens (1,777 listings) — TokenWorks' own NFT. Two more of the top five, FWATokenWrapper (435) and FWAERC20Wrapper (395), are TokenWorks contracts that package other assets into listable ERC-721s. Third-party collections in the top ranks are Art Blocks Explorations (1,314), Nakamigos (558), Collector Crypt (392), fwogs (231) and Otherdeed Expanded (193).

The single top-backed listing is id 136185: a CryptoPunks 721 wrapper token (0x00000000...5C5C2F, etherscan) backed with 300 ETH, holding a 9.365 ETH pot.


Governance Configuration

The contract emitted 43 ConfigSet events: 21 from the constructor and 22 owner actions since. Every parameter change was made by the deployer EOA directly.

DATE CHANGE FROM TO
2026-07-16 Whitelist manager delegated to FWAWhitelist — 0x854352b2...5e17c3 (etherscan)
2026-07-16 Payout address moved to Splitter deployer EOA 0x1C175b9F...373Bfe (etherscan)
2026-07-20 Acquisitions opened disabled enabled
2026-07-23 topListingShareBps 500 (5%) 100 (1%)
2026-07-29 minBacking 0.01 ETH 0.05 ETH
2026-07-31 surchargeBps 1000 (10%) 500 (5%)
2026-08-04 protocolFeeToTokenBps 0 8000 (80%)
2026-08-04 surchargeBps 500 (5%) 250 (2.5%)
2026-08-04 settlementDiscountBps 8500 (85%) 9000 (90%)
2026-08-06 protocolFeeToTokenBps 8000 (80%) 10000 (100%)

Six of those changes were made inside a disable/re-enable window, visible in the log as paired ACQUISITIONS_ENABLED writes minutes apart. The gate is narrower than that pattern suggests: setUint reverts with AcquisitionStateLocked only when unsettledAcquisitionCount != 0, not when acquisitions are enabled, so pausing is a convenient way to drain the queue rather than a requirement. The 2026-08-06 change to protocolFeeToTokenBps was made with no pause at all. Two of the six pauses enclosed no config change. Either way the constraint applies to timing only, not to magnitude.

The direction of travel is consistent: the purchaser's surcharge fell from 10% to 2.5%, their ETH exit improved from 85% to 90% of backing, and protocol revenue was redirected from the payout address entirely into the FWAToken buyback. The net effect is more favourable purchaser economics. We have no statement from the team on the reason.


Summary of Observations

FWA is an NFT pool where a depositor names their own price and their own odds in a single number, and a purchaser buys a random draw against the resulting distribution. The pricing identity holds — the harmonic mean we computed independently matches the contract's figure — and the accounting reconciles against a full reconstruction of chain state. We did not survey comparable designs, so we make no claim about how unusual the mechanism is.

The pool is solvent to within 157,011 wei of dust at block 25733839, with all eight liability components rebuilt from primitive chain state instead of read off the contract's own aggregates, and the rounding bias running in the contract's favour on every path we read. The expected-value pricing claim is verified: computing the harmonic mean of 5,770 backings independently reproduces the contract's internal figure exactly. We found no code path in which one listing's escrow settles another's obligation, which is what makes the reconciliation look structural rather than incidental.

On concerns, the dominant one is governance rather than code. A single externally-owned account with no multisig and no timelock owns the pool, the rewards module, the VRF service, and the Chainlink subscription, and holds 1,088 ETH besides. Its powers over the 1,370 ETH in the pool are bounded asymmetrically: depositor principal is protected by a hard-coded 5% cap on settlement fees, but depositor yield is protected only by a 100% ceiling on the acquisition fee — the owner may take the entire fee stream at any idle moment, effective immediately. The VRF coordinator address is likewise owner-replaceable while the pool is quiescent, which places the integrity of the randomness in the same hands.

Withdrawals and re-pricing are blocked whenever any acquisition is unresolved, which is mechanically necessary — removing weight would steer a paid-for draw — but the pool issued 819 acquisition requests in the eight hours before the snapshot, so depositors should not assume exit is available on demand. And the public repository is not the deployed code: it is a single-commit snapshot from eight days before deployment, missing the refactor that removed the Uniswap V4 integration and moved VRF pricing into an external service. Anyone reviewing FWA from GitHub is reviewing something that was never deployed.

Several mechanisms map directly onto specific attacks: commit-before-request sequencing, the staging queue that keeps new deposits out of an already-priced draw, ordered settlement with per-request slippage tolerances snapshotted at request time, best-effort NFT delivery so a hostile collection cannot block the ETH legs, and pull payments throughout. Against that sits unaudited complexity — a segment tree, a staging FIFO, a sequence ledger, and a dividend accumulator all interacting — and a trust model that concentrates everything in one key.

We read the verified source and reconstructed state from the chain. We did not fuzz, formally verify, or review the external rewards, whitelist, or VRF service contracts in depth. Anyone with money at stake should commission a professional audit and verify the numbers here themselves using the commands in the methodology.


References

RESOURCE NOTES
Etherscan — FWA verified source The authoritative source for this analysis. 2,372-line FWA.sol plus Solady and Chainlink dependencies.
token-works/fwa-relaunch Public repository. Single commit, 2026-07-08. Diverges from the deployed contract; used only for design context.
Fake World Assets documentation Protocol's own description of positions, weighting, pricing and settlement.
Chainlink VRF v2.5 documentation Subscription model, callback semantics, and the requestRandomWords interface used here.
Solady Source of ERC721, Ownable, ReentrancyGuard and SafeTransferLib used by the contract.
TokenWorks Project Overview DNZN's umbrella research on TokenWorks and its other works.

Change Log

DATE AUTHOR NOTES
2026-08-11 Artificial. Generated by robots. Gas: 1.3 mtok
2026-08-11 Denizen. Reviewed, edited, and curated by humans.