1PEG
A protocol-level resolution to Unipeg's flaws.
Unipeg proved hook-based collectibles work. It also proved a single global seed updated at swap time can be flash-loan farmed, and that non-hook pools let attackers replay the seed to mint twins of rare uPegs.
1PEG removes the seed entirely. Identity is per-slot and fixed at deploy. Traits commit to a future block before they're revealed, so buyers can't simulate the outcome.
Each slot in a batch buy gets its own future-block commitment, so reveals stagger across blocks. Trait farming would require foreknowledge of those hashes, which the EVM doesn't provide.
Built different.
Slots, not seeds.
Unipeg's identity model derives every uPEG's appearance from a single global seed updated in afterSwap. 1PEG removes that primitive entirely. Identity is bound to one of 10,000 permanent slot IDs assigned in order as buyers arrive. Slot uniqueness is enforced by construction, not by policy, so cross-pool replay attacks are mathematically impossible.
Sealed at commit, revealed by future entropy.
When afterSwap assigns your slot, the contract writes a commitBlock and a revealBlock = current + 5. Traits are computed as keccak256(slotId, blockhash(revealBlock)) — a hash that depends on a future block the buyer cannot see at purchase time. Calling reveal(slotId) after the delay flips the slot. The reveal call is permissionless; anyone can flip any sealed slot.
Per-slot staggered entropy.
Every slot in a batch buy gets its own future-block commitment. A buyer minting 100 slots in a single tx receives 100 independent reveal blocks (N+5, N+6, N+7, all the way to N+104), each pulling entropy from a different future blockhash. There is no "see what you got" moment for a batch — the reveals stagger across blocks, and each block's hash is independently unpredictable. Trait farming requires foreknowledge of those hashes, which the EVM does not provide.
Provable rarity, fixed at deploy.
The slot space is 10,000, immutable, and assigned in order. The rarity distribution emerges deterministically from the commit-reveal entropy — there is no admin, no oracle, no off-chain process that can adjust it. What's rare on day one stays rare forever. No new slots can be minted, no existing slots can be re-rolled, no twin generation is possible because every slot's hash is bound to its own commit and reveal blocks.
Rendered fully on-chain. No IPFS, no fallback.
Each 1PEG renders as inline SVG composed by the contract from on-chain pixel data — body, mane, tail, eyes, accessories, all stored in the renderer's storage. tokenURI returns a base64 data-URI containing the SVG and metadata. There is no metadata server, no IPFS pin, no host that can vanish. The art is part of the contract.
Why this design
The first generation of Uniswap v4 hook collectibles proved the primitive worked. Unipeg shipped a swap-as-mint mechanic that no project had attempted, got onto the routing API allowlist, and demonstrated that hook architecture could host objects, not just fee logic. It also exposed two structural exploits that the design couldn't survive at scale: deterministic identity computed at swap time, and a global seed updated only on the v4 hook.
1PEG keeps what worked: hook-based assignment, fully on-chain rendering, ERC-20 transferability. And it replaces what didn't. Identity moves from "computed at swap" to "fixed at deploy." Entropy moves from "current block" to "future block." Each slot's appearance is bound to a hash that does not exist at the moment of purchase. Each change is a direct response to a documented attack against the prior design.
Reveal mechanics
Reveal is a separate transaction, intentionally. Auto-revealing on assignment would collapse the commit-reveal scheme back into a one-block determination, which is exactly what we're avoiding. Lazy reveal also keeps gas on the buyer who wants to see what they got, not on every transfer that touches the slot.
When reveal(slotId) is called, the contract reads blockhash(revealBlock) and finalizes the trait hash. If the reveal block has aged past the EVM's 256-block hash window, a deterministic fallback uses keccak256(slotId, commitBlock) instead. The fallback is unfarmable after the fact but is technically known at commit time, so holders are economically motivated to reveal promptly.
Constraint summary
TOTAL_SLOTS = 10,000 (immutable) REVEAL_DELAY = 5 blocks MAX_SLOTS_PER_TX = 2,000 Pool fee: 1% (10,000 ppm) Tick spacing: 200 Hook permissions: afterAddLiquidity, afterSwap (everything else: false) Renderer: stateless, on-chain SVG composition Token: ERC-20 with slot-based identity overlay Ownable2Step, no upgradeability, no proxy
Failure modes addressed
Cross-pool seed replay. Impossible. There is no global seed to replay. Each slot's identity is derived from its own commitBlock and the blockhash of its own revealBlock — values that are unique per slot and don't exist on any other pool.
Predictable batch sniping. Defeated by future-block entropy and per-slot staggered revealBlocks. A buyer minting many slots at once gets that many different future block hashes, none of which exist at the moment of the swap. Trait outcomes are not simulable at buy time.
Long-term rarity dilution. Prevented by the fixed slot space. The rarity distribution is committed at deploy. No new slots can be added; no existing slots can be re-rolled. Twin generation across alternate pools is impossible because each slot's hash is bound to its own commit/reveal blocks.