agents4fun
Summary: One pnpm+Foundry monorepo (repo agent-wl, product “Agents 4.Fun”, powered by depunks) shipping TWO on-chain products — a fair Whitelist/allowlist tool and a Sweepstakes mint-as-ticket tool — both using Chainlink VRF v2.5 + Solady LibPRNG; no prize token is ever issued by the whitelist.
What it is
“Agents 4.Fun” is a multichain, on-chain fair-random-selection app where humans and AI agents apply through the same permissionless on-chain path. Two products live in the repo:
- Whitelist — a paid, token-gated allowlist tool; the draw picks winning wallets, exported off-chain (e.g. an OpenSea allowlist). It issues no rewards or token itself.
- Sweepstakes (“sweep”) — mint-as-ticket: each mint of a creator’s chosen NFT source is one ticket; once tickets cover a target NFT price, the pooled funds buy that NFT and a VRF draw picks the winning ticket.
Product name in the UI is literally “Agents 4.Fun” (apps/web/src/routes/landing.tsx); “Powered by DePunks (depunks.club)”.
Note: an earlier framing (“sweepstakes + NFTSweeps + our-own-PRNG”) was inaccurate vs the code. The whitelist uses Chainlink VRF v2.5 (not a homegrown PRNG for the seed), and the two products are distinct.
Stack / where it lives
- Repo:
~/Documents/localhost/agent-wl(remotegithub.com/damir5/agent-wl); active branchdev. - pnpm 11 + Foundry monorepo, Node ≥ 24.
README.md,CLAUDE.md apps/web= TanStack Start + React 19.2 + Vite 8 + Tailwind v4 (wagmi/viem, RainbowKit, Better Auth SIWE, oRPC).apps/web/package.jsonapps/backend= Effect 4 (singleeffectpackage) →/api(OpenAPI + HTTP MCP) and/rpc(oRPC). Keeper worker signs only operational txs, never user txs.README.mdapps/indexer= Ponder → Postgres read model.packages/db= Kysely (off-chain tables only).packages/config= ChainRegistry.- Chains: Ethereum mainnet, Base, Ethereum Sepolia, Base Sepolia (+ local Anvil 31337).
CLAUDE.md - “Dash” light reskin: the web UI has a light/condensed “dash.foogy.xyz style” token set (off-white,
#111text,#ff5a1faccent, flattened — no neumorphism), scoped to.protocol-shellinapps/web/src/styles.css(~line 264). This is separate from the DePunksdesign.mddark system.
Product 1 — Whitelist (allowlist)
- Token-gated entry via a required on-chain
IEligibilityHook; built-in table-driven StandardHook gates by collection: ERC-721 per-token single-use, ERC-1155 up to held balance capped at a configured per-id supply.evaluate(...) → Grant[]{tier, useKey, capacity}, staticcall, 300k gas, fail-closed.docs/hook-abi.md - Tiers + per-wallet caps: ordered tiers (tier 0 highest), strict-priority draw; per-tier per-wallet caps enforced by the contract, not the hook.
docs/eligibility-and-tickets.md - Draw: single Chainlink VRF v2.5 seed → Solady LibPRNG partial Fisher-Yates per tier, batched with a persisted cursor; ticket-level wins by default, optional one-win-per-wallet.
README.md - Winner export: after the draw you export winning wallet addresses as CSV (e.g. an OpenSea allowlist), gated behind chain finality. RPC
winnerCsvData; REQ-031 / REQ-127.docs/eligibility-and-tickets.md,docs/requirements.md - Fees: per-ticket entry fee + one-time setup fee, both non-refundable, swept to the project Safe in the collecting tx (default 0.01 ETH). Contract never holds fee balances.
README.md - No prize pool / no token: the system issues no rewards; winners just land on the exported list. Optional owner-at-pick mode (ERC-721 only) reassigns a win to the token’s current owner at draw time.
README.md - Contract:
WhitelistRouter(UUPS, per-whitelistIdmappings, Safe-owned) +StandardHook; 38 forge tests.README.md
Product 2 — Sweepstakes (“sweep”, mint-as-ticket)
Contracts under packages/contracts/sweep/src/.
- Mechanic: a sweep is bound to a mint source (
mintContract+mintDeployBlock) at deploy. Mints are indexed (Ponder) → each mint = 1 ticket, funded on-chain via keeper-signed EIP-712FundingBatch(fundTickets). A round has atargetPrice(the live NFT ask); once accumulated ticket value covers it, the keeper callsattemptPurchase, which atomically buys the target NFT, then a VRF v2.5 draw picks the winning ticket. Overflow rolls to the next round (multi-round).SweepMultiRoundBase.sol,base/RoundStorage.sol - SweepFactory (UUPS, Ownable): deploys strategy-specific sweep proxies (
deployNFTStrategySweep/deployPunkStrategySweep), owns the single VRF v2.5 subscription, holds VRF config, keeper, 4 team wallets + special-fee wallet.SweepFactory.sol - Strategies:
SweepMultiRound_NFTStrategy(generic ERC-721 via a marketplace adapter) andSweepMultiRound_PunkStrategy(buys CryptoPunks directly viabuyPunk/transferPunk, requires exact price match since punks predate ERC-721).SweepMultiRound_PunkStrategy.sol,test/unit/SweepPunkStrategy.t.sol - Fee split (hardcoded BPS): 90% to round balance, 2% split across 4 team wallets, 8% to special-fee wallet; non-refundable.
.fdb/domain-language/contract-fee-split.md - Note: the sweep product was merged into agent-wl (remote branch
merge/sweepstakes-into-aw); it originated from a separatesweepyrepo.
Agent surface
/apiis the stable public agent/HTTP-MCP surface (discovery, whitelist reads, unsigned-tx construction). Agents sign and broadcast their own txs; the backend never signs applicant txs.README.md- Daily
pnpm agents:snapshotenumerates every ERC-8004-bound agent across OpenSea agent-category collections — ties into opensea-erc8217 / depunks.CLAUDE.md
Open questions
- Whether the “dash” light theme is the default active state or gated on the
.protocol-shell/.darkruntime class was not fully traced. - Exact
agents4.fundomain string not found in-repo (UI shows “Agents 4.Fun” with a space).
Sources
~/Documents/localhost/agent-wl/README.md,CLAUDE.md,design.mdagent-wl/docs/eligibility-and-tickets.md,docs/hook-abi.md,docs/requirements.md,docs/read-model-schema.mdagent-wl/packages/contracts/sweep/src/*.sol,packages/contracts/sweep/test/unit/*,.fdb/domain-language/contract-fee-split.md,.fdb/bounded-contexts/sweep-lifecycle.mdagent-wl/apps/web/package.json,apps/web/src/styles.css,apps/web/src/routes/landing.tsx- Related: depunks, opensea-erc8217, raw/agent-wl-sweep-notes