Skip to content

Artifacts

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

METADATA
Contract Address 0xb276f62d...1eac1c (etherscan)
Network Ethereum Mainnet
Analysis Date 2026-08-11
Snapshot Block 25733839

Runtime Bytecode

The deployed contract bytecode, 21,425 bytes — 3,151 below the EIP-170 ceiling of 24,576.

Source: Etherscan — Contract Code

Command:

export ETH_RPC_URL=https://eth.llamarpc.com
cast code 0xb276f62db0ce8ca2ca5bc522695be604521eac1c
cast codesize 0xb276f62db0ce8ca2ca5bc522695be604521eac1c

Artifact (dispatcher prologue, first 320 hex characters):

0x60806040526004361015610011575f80fd5b5f5f3560e01c80630793e5fd14612e4c5780630986a5a114612e13
5780631b9bc52514612dce5780631fe543e314612d7057806320bd63ba14612c2b578063249d39e914612c0f5780
6324f7469714612bec5780632569296214612ba35780632b0b964114612b865780632c8bea3314612b4d5780632f
a14f4914612a3357806334b1670f14612a165780633531aed5146129de57806335390e961461295a5780633

The dispatcher is a linear selector comparison chain in ascending order, beginning with depositorReclaimBacking (0x0793e5fd) and claimTopSpot (0x0986a5a1). A 92-function contract compiled at runs = 1 produces this shape rather than a binary search table, because the optimizer is minimising code size rather than dispatch gas.

Artifact (final 100 bytes, 200 hex characters):

2b50b5145049b1d65d5a3b89394dc478bf60e39b57c30e2533ff20d9a30ad64c91a54af68be0079c5316591413
44cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e088ebc94b0ff4693b3d25995dc7c5c4e5683a8ca7de00
836773ca24c8b69d78e3

The runtime ends in event topic constants rather than a metadata CBOR block. 0x8be0079c...6457e0 (events) is the standard OwnershipTransferred(address,address) topic used by Solady's Ownable. The absence of trailing metadata matches the appendCBOR: false setting shown below.


Creation Bytecode

Full deployment payload including constructor code and the five ABI-encoded arguments.

Source: Etherscan — Creation TX

Command:

export ETH_RPC_URL=https://eth.llamarpc.com
cast tx 0xa711a902fde7b46795c52c6660939ca8898bf01ac010dfef9856ea7112fd3c78 input

Artifact (constructor prologue, first 356 hex characters):

0x60a03461048957601f61588738819003918201601f19168301916001600160401b0383118484101761048d57
80849260a09460405283398101031261048957610047816104a1565b9060208101519160408201519160608101
519063ffffffff821680920361048957608061007491016104a1565b6003546006600455601e6009556005600a
55600b8054600160401b62ff000160801b0319167201000000000000000000010000000000000000179055

The immediate-value writes visible in that prologue are the contract's default parameter assignments, and they can be read straight out of the deployment: 6004 writes 6 to slot 4 (maxActivationsPerAcquisition), 601e6009 writes 30 to slot 9 (selectionTimeoutBlocks), and 6005600a writes 5 to slot 10 (maxAcquisitionsPerTx). All three match the values still in force at the snapshot block.

Constructor arguments (decoded from the trailing 160 bytes):

coordinator       = 0xd7f86b4b8cae7d942340ff628f82735b7a20893a
subId             = 0xbe3fb16e567de94add08d0270be5e987eab08ac5cddb073ca79c06e16e0ffd33
keyHash           = 0x8077df514608a09f83e4e8d300645594e5d7234665448ba83f51a50f842bd3d9
callbackGasLimit_ = 0x00000000000000000000000000000000000000000000000000000000000dbba0  (900,000)
service           = 0xa084c33fb7a467307452898b8d58165ebd2e5d9f

The constructor validates all five before assigning: it reverts InvalidConfig() on a zero coordinator, a zero subscription id, a zero key hash, a callback gas limit outside 150,000–2,500,000, or a service address that is zero or has no code. It then sets the deployer as both owner and initial payout address, and emits 21 ConfigSet events so an indexer can reconstruct the full starting configuration from logs alone without a contract read at the deploy block.


Verified Source Code

Source verified on Etherscan with an exact match. Nine files: two written for this project, four from Solady, three from Chainlink.

Source: Etherscan — Contract Source

Command:

curl -s "https://api.etherscan.io/v2/api?chainid=1&module=contract&action=getsourcecode\
&address=0xb276f62db0ce8ca2ca5bc522695be604521eac1c&apikey=$ETHERSCAN_API_KEY"

FILE LINES BYTES ROLE
src/FWA.sol 2,372 122,864 The pool. All application logic.
src/FWAConfigKeys.sol 52 2,969 Numeric key constants for the three owner dispatchers.
lib/solady/src/tokens/ERC721.sol 913 40,004 Imported for the ERC721 type used in external calls. FWA does not inherit it.
lib/solady/src/auth/Ownable.sol 278 12,551 Owner role. Uses a fixed storage slot, not a sequential one.
lib/solady/src/utils/ReentrancyGuard.sol 55 2,333 nonReentrant, backed by Transient Storage.
lib/solady/src/utils/SafeTransferLib.sol 680 32,803 forceSafeTransferETH for every ETH payout.
lib/chainlink-evm/.../IVRFCoordinatorV2Plus.sol 38 2,141 Coordinator interface.
lib/chainlink-evm/.../IVRFSubscriptionV2Plus.sol 104 3,952 Subscription interface, including pendingRequestExists.
lib/chainlink-evm/.../VRFV2PlusClient.sol 27 650 Request struct and _argsToBytes helper.

FWA declares contract FWA is Ownable, ReentrancyGuard and is not itself an ERC-721. It imports Solady's ERC721 purely as a typed interface for calling into listed collections.

Compiler settings:

{
  "optimizer": { "enabled": true, "runs": 1 },
  "viaIR": true,
  "evmVersion": "prague",
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": false
  }
}

Three of these are size decisions rather than defaults. runs = 1 optimises for deployed size over runtime gas. viaIR enables the IR pipeline, whose function specializer the source works around in one place by passing a runtime address instead of a boolean flag, explicitly noting that "the bytecode budget can't afford two copies". And appendCBOR: false with bytecodeHash: none strips the trailing metadata block entirely, reclaiming roughly 50 bytes. Taken together with the collapse of the per-knob setters into three generic dispatchers, the settings are consistent with optimising against the EIP-170 ceiling; the runtime landed 3,151 bytes under it.


Additional Artifacts

Contract ABI

92 functions, 38 events, 41 custom errors.

Command:

curl -s "https://api.etherscan.io/v2/api?chainid=1&module=contract&action=getabi\
&address=0xb276f62db0ce8ca2ca5bc522695be604521eac1c&apikey=$ETHERSCAN_API_KEY"

The complete selector table is in functions.md.

Constructor Configuration Events

The constructor emitted 21 ConfigSet events in the deployment transaction, establishing the full starting parameter set on-chain.

Command:

cast keccak "ConfigSet(uint256,uint256)"
# 0x150110afd46e9924086bf85c855aae25722518b293155bf0ae689dd99a2e88cc

curl -s "https://api.etherscan.io/v2/api?chainid=1&module=logs&action=getLogs\
&address=0xb276f62db0ce8ca2ca5bc522695be604521eac1c&fromBlock=25546793&toBlock=25546793\
&topic0=0x150110afd46e9924086bf85c855aae25722518b293155bf0ae689dd99a2e88cc\
&page=1&offset=1000&apikey=$ETHERSCAN_API_KEY"

Artifact (constructor defaults, decoded — the 17 economic and operational keys; the four VRF wiring keys are shown under Constructor Bytecode above):

SURCHARGE_BPS                    = 1000      (10%)     → later 500, then 250
SETTLEMENT_DISCOUNT_BPS          = 8500      (85%)     → later 9000
OWNER_ACQUISITION_FEE_BPS        = 100       (1%)      → unchanged
OWNER_SETTLEMENT_FEE_BPS         = 100       (1%)      → unchanged
SETTLEMENT_WINDOW                = 86400     (24h)     → unchanged
FINALIZE_WINDOW                  = 604800    (7d)      → unchanged
MIN_BACKING                      = 1e16      (0.01 Ξ)  → later 5e16
CALLBACK_GAS_LIMIT               = 900000              → unchanged
REQUEST_CONFIRMATIONS            = 3                   → unchanged
MAX_ACTIVATIONS_PER_ACQUISITION  = 6                   → unchanged
SELECTION_TIMEOUT_BLOCKS         = 30                  → unchanged
ACQUISITIONS_ENABLED             = 0         (loading) → opened 2026-07-20
WHITELIST_ENABLED                = 1                   → unchanged
TOP_LISTING_SHARE_BPS            = 500       (5%)      → later 100
TOP_THRESHOLD_BPS                = 1000      (10%)     → unchanged
RETAINED_TO_PROTOCOL             = 1                   → unchanged
PAYOUT_ADDRESS                   = deployer            → later the Splitter

The full post-deployment change history is tabulated in contract-analysis.md.

Storage Snapshot

All 62 sequential slots were read at block 25733839. Full decoding is in storage-layout.md.

Command:

export ETH_RPC_URL=https://eth.llamarpc.com
for i in $(seq 0 61); do
  printf "%2d " $i
  cast storage 0xb276f62db0ce8ca2ca5bc522695be604521eac1c $i --block 25733839
done

Artifact (the slots carrying current economic parameters):

14 0x00000000000000000000000000000000000000000000000000000000000000fa   surchargeBps           250
16 0x0000000000000000000000000000000000000000000000000000000000002328   settlementDiscountBps  9000
19 0x00000000000000000000000000000000000000000000000000b1a2bc2ec50000   minBacking             0.05 ETH
20 0x0000000000000000000000000000000000000000000000000000000000000064   ownerAcquisitionFeeBps 100
21 0x0000000000000000000000000000000000000000000000000000000000000064   ownerSettlementFeeBps  100
23 0x0000000000000000000000000000000000000000000000000000000000000064   topListingShareBps     100
51 0x0000000000000000000000000000000000000000000000000000000000002710   protocolFeeToTokenBps  10000

Pool State Reconstruction

Every listing id from 1 to 149,854 was read via Multicall3 at block 25733839, then partitioned by status and summed. This is the dataset behind the solvency reconciliation.

Command (one listing; the sweep batches these through Multicall3 at 0xcA11bde0...76CA11 (etherscan)):

cast call 0xb276f62db0ce8ca2ca5bc522695be604521eac1c \
  "listings(uint256)(address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint64,uint8)" \
  136185 --block 25733839

Artifact (reconstructed aggregates versus the contract's own counters):

                            RECONSTRUCTED                                CONTRACT GETTER      MATCH
active listings             5,770                                        5,770                yes
Σ weight                    72357566815035813943552                      72357566815035813943552   yes
Σ feeShare                  5,770                                        5,770                yes
Σ weight × value            5769999999999999999537847588424043513363     5769999999999999999537847588424043513363   yes
tree root                   —                                            72357566815035813943552   equals Σ weight
status totals               5,770 + 56 + 9,314 + 134,714 = 149,854       nextListingId − 1 = 149,854   yes

harmonic mean of 5,770 backings   0.079742869391249362 ETH
weightedBackingTotal / totalWeight 0.079742869391249362 ETH               identical

Solvency Reconciliation Data

Artifact:

COMPONENT                                  WEI                      ETH
Active listing backing (5,770)             1246219052679687862152   1246.219052680
Allocated listing backing (56)                3788921919190696970      3.788921919
Uncredited fee accumulator                   70370386500834949333     70.370386501
Credited 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

External Dependency Snapshot

Artifact:

Chainlink subscription 0xbe3fb16e...0ffd33
  LINK balance          0
  native balance        79.642307133969197798 ETH
  request count         140,481   (equals lastIssuedSequence)
  owner                 0x019817aD02a31B990433542097bE29D97613E8Cb
  consumers             [0xB276F62DB0ce8CA2Ca5bc522695bE604521eAc1c]

Coordinator  0xd7f86b4b...20893a  VRFCoordinatorV2_5   (Solidity 0.8.19)
VRF service  0xa084c33f...2e5d9f  FWAVRFService        fwa() → FWA,  0.535914540816156347 ETH held
Rewards      0x6a1a1c0c...92fc78  FWARewards           fwa() → FWA,  token() → FWAToken
                                                       holds 11,258,552.93 FWAToken
Splitter     0x1c175b9f...373bfe  Splitter             payout destination, 166.704664240924156556 ETH held

Repository Divergence

The public repository is not the deployed code — the most consequential divergence we found, and the one to establish before reading FWA's source from GitHub.

Command:

gh api repos/token-works/fwa-relaunch --jq '{created_at,pushed_at,license,default_branch}'
git clone --depth 50 https://github.com/token-works/fwa-relaunch.git
grep -n '^import\|^contract ' fwa-relaunch/src/FWA.sol

Artifact:

repo HEAD        1085bf6  "FWA relaunch — initial public release"   (single commit, 2026-07-08)
deployed         2026-07-16, eight days later

                          REPOSITORY                    DEPLOYED
src/FWA.sol lines         2,756                         2,372
declaration               FWA is Ownable,               FWA is Ownable,
                          ReentrancyGuard,              ReentrancyGuard
                          IUnlockCallback
Uniswap V4 imports        9 (IPoolManager, PoolKey,     none
                          TickMath, CurrencySettler, …)
FixedPointMathLib         imported                      not imported
FWAToken.sol import       yes (POOL_LP_FEE, …)          no
external interfaces       ITokenBurnable                IFWARewards, IFWAVRFService
FWAConfigKeys 3–6         VRF_SERVICE_GAS_ESTIMATE,     "intentionally unused … moved into
                          VRF_SERVICE_MARGIN_BPS,        the external FWAVRFService before
                          VRF_SERVICE_FLAT_WEI,          deployment"
                          VRF_AUTO_TOPUP_THRESHOLD

Repository files were cloned to private/clones/tokenworks-fwa/ for local reading and are not committed.