Nov 1, 2026

Blindfair

A fair launch protocol for Ethereum

Private wallets, public rules.

x.com/Blindfair

The simple version

The one-page overview, Nov 1, 2026

Blindfair is a token launchpad for Ethereum that I’m building as an independent developer. Each launch opens with a ten-minute pooled window where every contributor pays the same price, then moves to a Uniswap market that nobody controls.

The problem

On most launchpads, the price depends on who gets in first. Snipers buy in block 1, deployers bundle their own supply across dozens of wallets, and presale wallets hold a cost basis the public never gets. The first green candle is where those wallets exit into everyone else. Then the liquidity gets pulled, or the contract gets “upgraded”.

How a launch works

The market opens ten minutes after the deploy, at the window price
life of a launch · 4 steps and the refund case
  1. Create. One transaction deploys the token and its Uniswap pair. Supply is fixed at 1,000,000,000, and the creator receives none of it.
  2. Contribute. During the window, anyone can send ETH. No whitelist, no cap, no withdrawal. Nobody knows the final price before the close, the creator included.
  3. Settle. At the close, the price is fixed at ETH raised ÷ 500,000,000, and each contributor receives their ETH divided by that price, in tokens.
  4. Trade. 99% of the ETH and 495,000,000 tokens seed the Uniswap pool at exactly that price. The LP tokens go to the burn address.
  5. Unlock. Window tokens unlock linearly over 24 hours from the market open and can be claimed at any time.

If less than 1 ETH is raised, the launch is cancelled: all tokens are burned and every contributor is refunded in full, with no fee.

Example. A window raises 20 ETH. The price is 0.00000004 ETH per token, or 25,000,000 tokens per ETH, and the pool opens with 19.8 ETH against 495,000,000 tokens.

What it changes

  • Bots. You’ll see the deploy. You’ll buy in block 1. You’ll pay exactly what someone paid at minute 9. Splitting across wallets or raising your gas changes nothing.
  • Insiders. No team allocation, no presale, no private round. Every token anyone holds was bought, in the window or from the pool.
  • Dumps. One minute after the market opens, a holder can sell 0.07% of their allocation. If every holder sold everything they could after one hour, the price would fall by 7.9% at most.
  • Rugs. No owner, no admin key, no proxy, no transfer tax. There is nothing left to pull.
  • Downside. Burned liquidity and a capped supply put a floor under the pool: its price can never fall below 24.75% of the window price, in ETH.
  • Addresses. Tokens are deployed with CREATE2. The address is known before the token exists, and only the factory can ever deploy there. Knowing it early is worth nothing.

Fees

1% of the raise, charged once at settlement: half to the creator in ETH, half to the protocol. No trading tax, no claim fee. Swaps pay Uniswap’s standard 0.3%.

Project token

It launches alongside the launchpad, on Uniswap v4. 100% of the supply goes into the pool, the liquidity position is sent to a dead address, and there is no team allocation and no presale. Holders receive half of the protocol’s share, 0.25% of every raise on Blindfair, in ETH, pro rata to their holdings.

It isn’t launched on Blindfair, on purpose. The factory has no special path for anyone, me included: launching my own token there would make me the creator of that launch, with its fee and its timing. Keeping it separate keeps every launch on the factory free of insiders, and a problem in one system can’t touch the other.

The holders’ share depends on activity, since no raises means no fees, and it’s paid from the protocol’s fee address, not by the factory’s code. CA and launch date: announced on X only.

Next: private contributions

Phase 3 separates the wallet that pays from the wallet that receives, using fixed notes of 0.1, 1 or 10 ETH and zero-knowledge proofs. Association sets and sanctions screening keep hacked funds out, and cancelled launches refund publicly, so it can’t work as a mixer.

Limits

  • Fair isn’t profitable. Blindfair fixes how the price is formed, not where it goes.
  • Your final price is unknown when you contribute. What you see at that moment is your best case; every later contribution raises it.
  • After settlement, the pool is a normal Uniswap market, bots included.
  • Smart contracts can have bugs, and by design nobody holds a key to rescue funds.

Status

Tested on testnet before launch. The launchpad goes live on Ethereum mainnet, with the project token launched alongside it. Next: private contributions.

Not financial advice. Software in development; parameters can change before the audit. Blindfair does not review or endorse the tokens launched on it. Every rule and number on this page is specified in the full whitepaper.

The full version

A fair launch protocol for Ethereum · Whitepaper v0.3 · x.com/Blindfair · Nov 1, 2026

Abstract

Creating a token on Ethereum takes one transaction. Deciding who gets it, at what price, and who can sell it to whom is where launches are won and lost. In most launches today that decision is made by speed, privilege and visibility. Snipers buy in the deployment block. Creators bundle their own supply across dozens of wallets. Insiders receive allocations at prices the public never sees. Every profitable wallet becomes a signal for others to exploit. The people who lose are the ones who arrive as humans.

Blindfair is a launch protocol in which arrival order and insider status carry no economic value. Every launch opens with a ten-minute pooled window in which all participants pay one uniform price, whether they contributed in the first block or the last. No allocation exists outside that window: no creator share, no team share, no presale. When the window closes, the protocol seeds a Uniswap v2 pool at exactly the window price and burns the liquidity tokens. Opening allocations unlock linearly over 24 hours, starting when the market opens, so one minute after the market opens no participant can sell more than 0.07% of their allocation. Because the burned liquidity can never leave and the tradable supply is capped, the pool price in ETH can never fall below 24.75% of the window price, at any time. The contracts have no owner, no administrator and no upgrade path.

A later phase adds private contributions: fixed-denomination notes and zero-knowledge proofs that break the on-chain link between the wallet that pays and the wallet that receives, with association sets and sanctions screening so that privacy does not become a haven for stolen funds.

This paper specifies the mechanism, explains every parameter, proves the core properties, analyses the incentives of every actor, describes the privacy architecture and the smart contract interface, and lists, without softening, what Blindfair does not solve.

Contents

  1. Introduction
  2. Background and related approaches
  3. Design principles
  4. Design goals
  5. System overview
  6. Mechanism specification
  7. Parameter rationale
  8. Formal properties
  9. Incentives and market dynamics
  10. Privacy architecture
  11. Smart contract architecture
  12. Security analysis
  13. Economics
  14. Governance, team and immutability
  15. Application layer and how to verify a launch
  16. Compliance considerations
  17. Limitations
  18. Research directions
  19. Status
  20. Developer reference: contracts
  21. Developer reference: integration
  22. Deployment and verification
  23. Conclusion

Appendix A. Parameter summary · Appendix B. Price impact and floor derivation · Appendix C. Glossary · Appendix D. Frequently asked questions · Appendix E. References

1. Introduction

1.1 Context

A token launch is a market with no history. There is no previous price, no order book, no reputation. Whoever sets the first prices and receives the first allocation captures most of what follows. Five structural problems decide who that is, and in most launches all five work against the public.

1.2 The ordering problem

On a bonding curve, or in a pool seeded directly by a creator, price is a function of cumulative purchases. Each buy moves the price for the next one. Position in the transaction order is therefore worth money, and that value flows to whoever can buy position:

  • Bots that monitor factory contracts and the mempool, and submit buys the moment a token appears.
  • Searchers that pay block builders through priority fees and private order flow to land first.
  • Creators who bundle their own purchases with the deployment transaction, so they buy before anyone else can see the token [4].

By the time a person reads an announcement, opens a wallet and confirms a transaction, the cheapest supply is gone. They buy from the people who were faster.

1.3 The privilege problem

Presales, seed rounds, team allocations, advisor allocations, partner and influencer rounds share one feature: a price set before the public knows the token exists. However they are justified, they create holders whose cost basis the public can never match. Those holders’ rational strategy is to sell into public demand. Vesting schedules help when they exist and are honored, but they are usually configured by the same people who benefit from them.

1.4 The visibility problem

Every Ethereum address is public, forever. Trackers label wallets. Copy-trading bots mirror the entries of profitable addresses and front-run their exits. Large holders are watched, targeted, socially engineered and sometimes physically threatened. On a transparent ledger, skill is a liability: the better a wallet performs, the more it is exploited.

1.5 The dump problem

Whoever bought cheapest can sell immediately. In a typical launch the first strong green candle is the moment early wallets exit into the first wave of real buyers. The chart that attracts the public is often the chart that distributes supply to them at the top.

1.6 The trust problem

Launch contracts frequently carry owner keys: functions to mint, pause, blacklist, change taxes, withdraw liquidity or upgrade the code. Liquidity locks expire. Proxies can be repointed. Users are asked to trust the promises of people they have never met, about contracts they cannot read, with keys they cannot see.

1.7 Contributions

Blindfair addresses these problems with a deliberately small mechanism:

  1. Uniform clearing. All demand in a ten-minute window clears at one price. Ordering within the window is worthless (Proposition 1).
  2. A single public allocation. No allocation exists outside the window. There is nothing to configure, so there is nothing to hide.
  3. Price-matched, permanent liquidity. The pool opens at the window price (Proposition 4), and its liquidity can never be withdrawn.
  4. Linear unlock from market open. Opening allocations unlock over 24 hours, starting at settlement, which bounds early sell pressure independently of the raise size and of when settlement happens (Proposition 5).
  5. A permanent price floor. Burned liquidity and a capped tradable supply keep the pool price above 24.75% of the window price, forever (Corollary 5.1).
  6. No discretion. No owner, no admin, no proxy, constant parameters.
  7. Deterministic addresses. Token addresses are known before deployment, cannot be squatted, and give bots no advantage (Propositions 6 and 7).
  8. Private contributions (phase 3). Notes and zero-knowledge proofs separate the paying wallet from the receiving wallet, within a compliance framework.

1.8 The name

Blind, because in the window everyone commits before the price is known, creator and bots included, and because phase 3 blinds the link between the wallet that pays and the wallet that receives. Fair, because everyone pays the same price.

1.9 Structure of this paper

Section 2 reviews existing launch models. Sections 3 and 4 state principles and goals. Sections 5 and 6 specify the system. Section 7 justifies each parameter. Section 8 proves the core properties, including the price floor. Section 9 analyses incentives. Section 10 specifies the privacy layer. Sections 11 and 12 cover the contracts and their security. Sections 13 to 16 cover economics and the project token, governance, the application and compliance. Sections 17 to 19 cover limits, research and status. Sections 20 to 22 are the developer reference: contracts, integration, deployment and verification.

2.1 Bonding curves

A contract sells tokens along a predefined price curve. Price rises with every purchase, and liquidity typically migrates to a DEX when a threshold is reached. Bonding curves are permissionless and simple, but they maximize the value of ordering: the first buyer gets the lowest price by construction. They are the natural habitat of snipers and bundlers.

2.2 Direct pool listings

A creator deploys a token and seeds a DEX pool with tokens and ETH. The creator chooses the initial price, usually keeps part of the supply, and controls the LP tokens unless they burn or lock them. The first blocks after the pool appears are a race.

2.3 Presales and launch platforms with allocations

Tokens are sold before trading at a fixed price to whitelisted participants, often with tiers, staking requirements or identity checks. Insiders receive allocations by design. Fairness depends on the issuer’s honesty and on how vesting is configured.

2.4 Descending-price pools

Liquidity bootstrapping pools start at a high price that decays over time unless demand pushes it up. Waiting is rewarded, which neutralizes sniping, but the issuer controls pool parameters and the resulting liquidity, and participants buy at different prices.

2.5 Batch auctions

All orders in a period are collected and cleared at one price. This is the closest model to Blindfair’s window. Batch auctions usually allow limit prices, and they typically leave the issuer in control of supply, proceeds and post-auction liquidity.

2.6 Fair launches

“Fair launch” usually means no premine and no presale. It says nothing about ordering: a fair-launched token can still be sniped in its first block.

2.7 Privacy protocols on Ethereum

Shielded pools let users deposit assets and withdraw them to unlinked addresses using zero-knowledge proofs. Association-set designs, notably Privacy Pools [3], add a way for users to prove their funds do not come from a set of illicit deposits without revealing which deposit is theirs.

2.8 Comparison

PropertyBonding curveDirect listingPresaleDescending poolBatch auctionBlindfair
Advantage from being firstHighHighAllocation-basedNegative (waiting pays)None in batchNone in window
Insider allocation possibleThrough bundlesYesBy designYesIssuer-definedNo, by construction
Same price for all early buyersNoNoUsually, per tierNoYesYes
Immediate dump by early buyersYesYesDepends on vestingYesDependsBounded (linear, 24h from market open)
Liquidity controlled by issuerVariesUsuallyUsuallyYesUsuallyNever
Admin keys on tokenVariesVariesVariesVariesVariesNone
Privacy of participantsNoneNoneOften identity checksNoneNonePhase 3

Blindfair combines uniform clearing from batch auctions, the permissionless creation of bonding curves, the permanence of burned liquidity and, later, the unlinkability of shielded pools, while removing every discretionary lever an issuer would normally hold.

3. Design principles

3.1 Private wallets, public rules

Everything that governs a launch is public, verifiable and identical for everyone: code, parameters, timing, totals, the pool. Everything that belongs to a participant (who they are, which wallets they use, what else they hold) is their business. The current version delivers the first half. Phase 3, private contributions, delivers the second.

3.2 Code over promises

A guarantee belongs in this paper only if it is enforced by contract code that anyone can read. “We will lock liquidity” is a promise. “Liquidity tokens are minted to the burn address in the settlement function” is a guarantee.

3.3 Remove the reward, not the actor

Blindfair does not try to detect bots, block snipers, require captchas or maintain whitelists. Such defenses are arms races that sophisticated actors win. Instead, Blindfair makes the strategies worthless: being first, splitting across wallets and sandwiching earn nothing. Bots are welcome. They pay the same price as everyone.

3.4 Simplicity is a security property

Every parameter, branch and external dependency is attack surface. Blindfair’s core is a handful of functions with constant parameters, no oracle (outside phase 3 sanctions screening), no governance of its own and no upgradability. The proofs in Section 8 are short because the mechanism is short.

3.5 Honest limits

A protocol that claims to solve everything invites the scepticism it deserves. Section 17 lists what Blindfair does not solve, and the rest of this paper flags residual risks where they arise, including the external dependencies it cannot remove (§12.1).

4. Design goals

GoalStatementAchieved by
G1 Order independenceA participant’s outcome does not depend on when, within the window, they contribute.Uniform clearing (§6.5)
G2 No privileged supplyNo address receives tokens on terms unavailable to the public.Single public allocation (§6.3)
G3 No discretionNobody can change rules, pause, mint, tax or move liquidity after deployment.No owner, constant parameters (§14)
G4 Bounded early supplySupply sellable shortly after the market opens is a small, known fraction, independent of the raise and of when settlement happens.Linear unlock from settlement (§6.8)
G5 Price continuityThe market opens at the price window participants paid.Matched liquidity (§6.7)
G6 LivenessEvery launch can be settled, claimed or refunded by anyone, without operators.Permissionless functions (§6.6)
G7 VerifiabilityEvery property can be checked on-chain by anyone, at any time.Verified source, public state, events (§11, §15.3)
G8 UnlinkabilityThe paying and receiving addresses cannot be linked on-chain.Private contributions (§10), phase 3

5. System overview

5.1 Actors

ActorRolePrivileges
CreatorStarts a launch with a name and tickerNone after creation; receives half the fee, in ETH
ParticipantContributes ETH during a windowReceives a pro-rata allocation, unlocked over 24h from settlement
Market participantTrades the token on Uniswap after settlementNone
SettlerAnyone who calls settlement after the windowNone; no reward. Settling starts everyone’s unlock, so every participant has a reason to do it
Protocol fee recipientA constant address set at deploymentCan withdraw its credited balance, nothing else. Half of it is paid on to project token holders (§13.5)
Relayer (phase 3)Submits private binding transactionsReceives the fee the user signs into the proof; cannot change recipient or fee
Association set provider (phase 3)Publishes sets of approved depositsCan deny privacy for a deposit, never funds
Sanctions oracle (phase 3)Lists sanctioned addressesCan block new deposits from an address, nothing else
Uniswap governance (external)Controls the Uniswap v2 protocol feeCan divert 1/6 of swap fees (0.05% of volume); cannot touch pool principal (§6.7)

5.2 Components

  • Factory. The single contract that creates tokens and their pairs, runs windows, settles launches, seeds liquidity, tracks allocations and processes claims and refunds.
  • Token. A plain ERC-20 with fixed init code, 18 decimals and EIP-2612 permits [6]. No owner, no mint after construction, no tax, no blacklist, no pause.
  • Uniswap v2 pair. The token/WETH market [2], created at launch so its address is public from the first block, and seeded at settlement.
  • Application. A static, open-source interface. Optional: every function can be called directly.
  • Privacy module (phase 3). Merkle trees of note commitments, a proof verifier and relayer support, shipped with a new factory version.

5.3 Launch state machine

Every launch ends SETTLED or FAILED, and nothing can reverse it
launch state machine · 5 states, 2 terminal

CLOSED is implicit: it is derived from time, not stored. SETTLED and FAILED are terminal. Transitions are monotonic and cannot be reversed by anyone.

5.4 Timeline of a successful launch

T is the creation block. S is the settlement block, normally the first block after the window closes (§6.6).

TimeEvent
TCreator’s transaction deploys the token and its Uniswap pair. The window opens in the same block
T to T + 10 minContributions at a price not yet known, identical for all
T + 10 minWindow closes. Settlement becomes callable by anyone
SPrice fixed, pool seeded, LP burned, fees credited, unlock starts. Nothing is unlocked yet
S + 1 min0.07% of each allocation unlocked
S + 1 h4.17% unlocked
S + 6 h25% unlocked
S + 12 h50% unlocked
S + 24 h100% unlocked

6. Mechanism specification

6.1 Parameters

SymbolMeaningValue
STotal supply per token1,000,000,000
SoOpening supply500,000,000
SLLiquidity reserve500,000,000
ΔWindow length600 seconds
VUnlock period86,400 seconds
fLaunch fee1% (100 basis points)
fcCreator share of the fee50% of the fee
CminMinimum raise1 ETH
MAX_NAME, MAX_SYMBOLName and symbol length limits32 and 10 bytes
DEADBurn address0x000000000000000000000000000000000000dEaD

All parameters are compile-time constants. Section 7 explains each one.

6.2 Notation

SymbolMeaning
t0Timestamp of the creation block
te = t0 + ΔWindow end
tsTimestamp of the settlement block, ts ≥ te
ciTotal contribution of address i
C = Σ ciTotal raised
pUniform price, in ETH per token
aiAllocation of address i
φFee amount
EL, TLETH and tokens added to the pool
ui(t)Amount unlocked for i at time t
U(τ)Opening supply unlocked τ seconds after settlement, all participants together
FPermanent price floor (Corollary 5.1)

6.3 Token and pair creation

A creator calls createLaunch(name, symbol). The factory derives a salt from the caller’s address and their launch count n:

σ=keccak256(abi.encode(creator, n))\sigma = \mathrm{keccak256}(\mathrm{abi.encode}(\mathit{creator},\ n))
(1)

It then deploys the token with CREATE2 [1]:

address=keccak256(0xff ∥ factory ∥ σ ∥ keccak256(initCode))[12:32]\mathit{address} = \mathrm{keccak256}(\mathtt{0xff} \,\|\, \mathit{factory} \,\|\, \sigma \,\|\, \mathrm{keccak256}(\mathit{initCode}))[12{:}32]
(2)

The token’s constructor takes no arguments, so its init code is byte-identical for every launch and its address depends only on the creator and their launch count: a creator can publish the address before launching (predictToken). During construction, the token calls back into the factory to read the pending name and symbol, stores them, and mints all S tokens to the factory. The factory clears the pending values in the same transaction.

In the same transaction, the factory gets or creates the token/WETH pair on the canonical Uniswap v2 factory. “Get or create” matters: token addresses are predictable and the Uniswap v2 factory accepts any two addresses, so anyone can create the pair in advance. If createLaunch required a fresh pair, a squatter could block any launch. A pre-created pair is harmless: it holds no tokens and nobody can seed it, because no tokens exist outside the factory (Proposition 8).

Creating the pair at launch rather than at settlement has three effects: the market’s address is public from the first block, the most expensive deployment is paid by the creator rather than by an unrewarded settler, and settlement stays cheap.

Name and symbol must be non-empty and at most MAX_NAME and MAX_SYMBOL bytes; they are otherwise unvalidated. Tickers are not unique on Ethereum, and Blindfair does not try to make them unique. The application warns about tickers that imitate well-known assets (§15).

The window opens at the creation block’s timestamp t0. The factory contains no code path that allocates tokens to the creator, a team, a treasury or any address other than window participants and the pool.

6.4 Opening window

For t0 ≤ block.timestamp < te:

  • anyone may call contribute(token) with any positive amount of ETH;
  • contributions from the same address accumulate;
  • an address may contribute any number of times;
  • there is no minimum and no maximum per address;
  • there is no maximum total;
  • contributions are final and cannot be withdrawn;
  • no tokens leave the factory.

A contribution carries no price when it is made. Its price is determined at the close and is the same for every contribution. The window is defined in seconds, not in blocks (§7.3).

6.5 Clearing

At any time t ≥ te, anyone may call settle(token). If C < Cmin, the launch becomes FAILED (§6.10). Otherwise the launch becomes SETTLED and clears at the uniform price:

p=CSop = \frac{C}{S_o}
(3)

Each address i is allocated:

ai=⌊So⋅ciC⌋a_i = \left\lfloor \frac{S_o \cdot c_i}{C} \right\rfloor
(4)

Allocations are computed lazily at claim time from stored contributions and the stored total. Equivalently, a participant pays p per token and receives 1/p = So / C tokens per ETH.

6.6 Settlement procedure

settle executes these steps atomically:

  1. Check that the window has ended and the launch is neither settled nor failed.
  2. If C < Cmin, mark FAILED, burn S, emit Failed, return.
  3. Mark SETTLED and record ts = block.timestamp.
  4. Compute the fee φ = ⌊C · 100 / 10,000⌋, the creator share φc = ⌊φ / 2⌋ and the protocol share φp = φ − φc.
  5. Compute EL = C − φ and TL = ⌊So · EL / C⌋.
  6. Burn SL − TL tokens by transferring them to DEAD.
  7. Wrap EL ETH into WETH and transfer it to the pair; transfer TL tokens to the pair.
  8. Call mint(DEAD) on the pair, so the LP tokens go to the burn address.
  9. Credit φc to the creator and φp to the protocol.
  10. Emit Settled with the raise, the reserves added, the amount burned and ts.

There is no reward for calling settle, and none is needed. Each participant’s unlock starts at settlement (§6.8), so every participant has a direct reason to call it, and searchers who want the first trade on a new market call it themselves. The application offers it to any visitor of a closed launch. With the pair created at launch, settlement costs a fixed, modest amount of gas.

6.7 Liquidity

The pool is seeded with:

EL=C−φ=(1−f) CTL=⌊So⋅ELC⌋≈(1−f) SoE_L = C - \varphi = (1 - f)\,C \qquad T_L = \left\lfloor \frac{S_o \cdot E_L} {C} \right\rfloor \approx (1 - f)\,S_o
(5)

so that its initial price EL / TL equals p, and rounding can only push it up (Proposition 4). With f = 1%, the pool receives 495,000,000 tokens (to within one token) and 99% of the raise, and about 5,000,000 tokens are burned.

The LP tokens are minted directly to DEAD; Uniswap v2 also locks 1,000 units of liquidity at address zero on the first mint [2]. No function in the factory or the token can retrieve either. Anyone may add their own liquidity to the pool and remove it later; nobody can remove the burned position.

Every swap pays Uniswap v2’s 0.3% fee. Uniswap governance approved switching on the v2 protocol fee on 25 December 2025 [7, 8]: since then, 0.25% of each swap accrues to liquidity providers, including the burned position, and 0.05% goes to the Uniswap protocol. The burned position’s share is never withdrawn, so liquidity deepens with volume. Uniswap governance can switch its 0.05% on or off; it cannot touch the burned position’s principal (Proposition 5, step i).

6.8 Unlock

Opening allocations unlock linearly, starting at settlement, when the market opens:

ui(t)=⌊ai⋅min⁡(t−ts, V)V⌋u_i(t) = \left\lfloor \frac{a_i \cdot \min(t - t_s,\ V)}{V} \right\rfloor
(6)

In the settlement block nothing is unlocked, and the schedule runs from the first block in which the token can trade. This is what makes the early-supply bound unconditional: whatever the delay between the close and settlement, the market never opens with a backlog of sellable supply. Anchoring the unlock to the window end instead would let a settlement delayed by six hours open the market with 25% of every allocation sellable at once.

Total opening supply unlocks at So / V ≈ 5,787 tokens per second across all participants.

6.9 Claims

A participant may call claim(token) at any time after settlement, any number of times. The claimable amount is ui(t) − claimed_i. Unlocked tokens accumulate, so a participant never loses anything by claiming late.

claimFor(token, user) lets anyone trigger a claim on behalf of user. Tokens always go to user. This lets wallets, relayers and the application push tokens to holders, and lets fresh addresses receive tokens without holding gas (§10.10).

claimMany(tokens[]) claims several launches in one transaction.

Tokens bought from the pool after settlement are ordinary ERC-20 balances and are not subject to any unlock.

6.10 Fail-safe and refunds

If C < Cmin at the close:

  • the launch is marked FAILED;
  • all S tokens are burned and the pool is never seeded (the pair created at launch stays empty forever);
  • no fee is charged;
  • each contributor can call refund(token) to withdraw exactly ci.

Refunds are pull-based: a contributor whose address cannot receive ETH affects only themselves.

6.11 Fee accounting

Fees are credited, never pushed. The creator calls withdrawCreatorFees() to receive the total credited to their address across all their launches. The protocol fee recipient, a constant address fixed at deployment, calls withdrawProtocolFees(); half of what it withdraws is then distributed in ETH to holders of the project token (§13.5). A failing recipient cannot block settlement or any other user.

6.12 Rounding

All divisions round down:

  • Σ ai ≤ So, with at most one base unit (10⁻¹⁸ token) of residue per participant;
  • TL rounds down, so the pool’s opening price is at least p, never below;
  • unlock rounding is recovered at ts + V, when ui = ai exactly;
  • residues stay in the factory permanently, which makes them effectively burned;
  • an odd wei of fee goes to the protocol share.

Multiplications cannot overflow: So · ci is at most about 5·10²⁶ × 1.2·10²⁶ ≈ 6·10⁵², far below the 2²⁵⁶ ≈ 1.2·10⁷⁷ limit.

6.13 Edge cases

CaseBehavior
No contributionsC = 0 < Cmin: the launch fails, supply is burned, nothing to refund
Exactly CminSettles normally
Single contributorReceives all of So at price C / So, unlocked over 24h from settlement
Contribution in a block with timestamp ≥ teReverts. The sender pays only gas
settle called twiceSecond call reverts
claim before settlement, or in the settlement blockReverts: nothing is unlocked yet
refund on a settled launchReverts
Pair created by someone else before the launchUsed as is; it holds no tokens and nobody can seed it (P8)
WETH donated to the pair before settlementRaises the opening price at the donor’s expense; locked forever (P8)
Settlement hours after the closeThe pool opens later and the unlock starts later; nothing is sellable before the pool exists
ETH sent directly to the factoryReverts: the factory has no receive function
Tokens sent directly to the factoryPermanently stuck, equivalent to a burn
Contribution from a smart contract walletSupported. Refunds require the wallet to accept ETH
Creator launches several tokensEach uses the next launch count and gets a distinct address
Empty or over-long name or symbolcreateLaunch reverts

7. Parameter rationale

7.1 Supply: 1,000,000,000

A fixed, round supply makes every launch comparable at a glance: the same fraction means the same number of tokens everywhere. The figure matches common practice, so prices are displayed in familiar orders of magnitude. Supply has no economic effect on fairness: only proportions matter.

7.2 Split: 50% opening, up to 50% liquidity

Price continuity decides most of what the split might seem to decide. For the pool to open at p, it must hold TL = (1 − f) · So tokens, whatever the split (formula (5)). So the pool always holds 99% as many tokens as participants received, the early-supply bound and the floor are the same for any split (Appendix B), and about half of the circulating supply stays locked in the pool forever.

What the split does decide is feasibility and the burn. The reserve must cover the pool: S − So ≥ (1 − f) · So, so the opening share can be at most S / (2 − f), about 50.25% of supply. Fifty percent is the round figure just below that limit: the reserve exceeds what the pool needs by only 5,000,000 tokens, which are burned, so the nominal supply of one billion stays close to the 995,000,000 that can ever circulate. A smaller opening share would change neither the floor nor the depth of the pool; it would only burn more of the nominal supply.

7.3 Window: 10 minutes

The window must be long enough for a person who sees an announcement to open a wallet and confirm a transaction, including on mobile and during congestion. It should be short enough to keep momentum and to limit the time ETH sits in the contract. Since being first is worth nothing, there is no reason to make the window longer than people need. Ten minutes is 50 slots at Ethereum’s current 12-second slot time: long enough that censoring a launch requires many consecutive colluding builders (§12.3). The window is defined in seconds, so a future change of slot time changes the number of blocks, not the duration.

7.4 Unlock: 24 hours, linear, from settlement

Linear unlock removes the cliff, the single moment when everything becomes sellable at once. Twenty-four hours covers every time zone and gives the market a full day to form a price before participants can exit fully. The clock starts at settlement because that is when selling becomes possible; starting it earlier would hand the first buyers a backlog of supply (§6.8). A longer unlock would protect early markets further but would keep capital locked longer and make Blindfair unattractive to ordinary participants. Section 8 quantifies the protection: one minute after the market opens, a fully coordinated dump of everything unlocked moves the price by at most 0.14%.

7.5 Minimum raise: 1 ETH

A pool seeded with dust is trivial to manipulate and useless to trade. One ETH makes every Blindfair market start with meaningful liquidity, while staying low enough that small communities can launch. Below the minimum, everyone is refunded in full.

7.6 Fee: 1%, split in half

The fee rewards creators for bringing real demand, funds the protocol’s security and infrastructure, and pays holders of the project token (§13.4, §13.5). Paying the creator in ETH rather than tokens is deliberate: a token reward is supply waiting to be sold into the market, while an ETH reward gives the creator nothing to dump. The split makes self-funding strictly unprofitable (Proposition 11). There is no trading tax, because taxes are the most common lever for hidden extraction.

7.7 Uniswap v2

Uniswap v2 is the most battle-tested AMM on Ethereum, has a simple full-range constant-product model, and lets the protocol seed and burn liquidity in a few auditable calls. Every aggregator, wallet and chart site indexes v2 pairs from their first block. Concentrated-liquidity designs would require choosing ranges, which is a discretionary decision with no neutral answer. Hooks in newer designs open interesting possibilities (§18.3) at the cost of more code.

The choice carries one external dependency: Uniswap governance controls the v2 protocol fee, switched on since December 2025, which takes 1/6 of the 0.3% swap fee [7]. I accept it because it touches fee income only, never the pool’s principal or the floor (Proposition 5).

7.8 No caps

Per-address caps assume one person equals one address. On Ethereum addresses are free, so caps are bypassed by anyone with a script and respected only by honest users. With uniform clearing, splitting earns nothing (Proposition 2), so caps would add complexity without adding fairness. There is no hard cap on the total either: more demand produces a higher price for everyone, not a sold-out launch reserved for the fastest.

7.9 Final contributions

If contributions could be withdrawn, a participant could display large demand to attract others and withdraw it in the last block. Finality makes the running total an honest signal.

7.10 Ethereum mainnet

Ethereum mainnet offers the deepest liquidity, the strongest settlement guarantees and the most credible neutrality. The cost is gas, which weighs on small participants and will rise for operations that create state once the Glamsterdam upgrade reaches mainnet (§11.8, §17).

8. Formal properties

Each property follows from the specification in Section 6. Propositions 1 to 4 concern the window, Proposition 5 and its corollary the market after it, 6 to 8 creation, and 9 to 11 accounting, liveness and incentives.

Proposition 1 (Order independence). For a fixed set of contributions, every allocation ai is independent of the times at which the contributions were made.

Proof. By (4), ai depends only on ci and C. Neither depends on timestamps, and the window accepts contributions on identical terms throughout [t0, te). Paying for earlier inclusion therefore buys nothing. ∎

Proposition 2 (Sybil neutrality). Splitting a contribution across several addresses never increases the total allocation.

Proof. Let a participant split c = Σj cj across k addresses. Then Σj ⌊So · cj / C⌋ ≤ ⌊So · c / C⌋, because a sum of floors is at most the floor of the sum. Splitting is neutral up to rounding, and rounding only works against the splitter. ∎

Proposition 3 (Price uniformity). Every participant pays the same price per token, p, up to rounding.

Proof. Participant i pays ci for ai = ⌊So · ci / C⌋ tokens, so their effective price ci / ai equals C / So = p up to rounding. ∎

Proposition 4 (Price continuity). The pool’s initial price is at least p. It exceeds p only by rounding, or by WETH that a third party donated to the pair before settlement.

Proof. By (5), TL ≤ So · EL / C, so EL / TL ≥ C / So = p, with equality up to rounding. A donation d adds to the ETH side only, giving (EL + d) / TL > p. ∎

Proposition 5 (Bounded early supply). Let U(τ) = So · min(τ, V) / V be the opening supply unlocked τ seconds after settlement. At every time τ ≥ 0 after settlement, whatever trades, donations or liquidity changes have happened, the pool price P(τ) satisfies:

P(τ)  ≥  p⋅(TLTL+U(τ))2P(\tau) \;\ge\; p \cdot \left( \frac{T_L}{T_L + U(\tau)} \right)^{2}
(7)

The bound does not depend on C, nor on when settlement happened.

Proof. Let L0 = √(EL · TL) be the pool’s initial liquidity, all of it locked: minted to DEAD, except 1,000 units locked by Uniswap at address zero.

(i) The locked liquidity never falls below L0. Swaps add their fee to the pool’s invariant. Liquidity added and removed by others is their own and leaves the locked share untouched. The Uniswap v2 protocol fee mints new shares only against the growth of √k since the last mint or burn, worth 1/6 of that growth [2], so the locked position keeps L0 plus 5/6 of its growth.

(ii) Tokens leave the factory only to the pool (TL, at settlement), to DEAD, and to claimants (at most U(τ) by time τ). At most TL + U(τ) tokens therefore exist outside the factory and DEAD, and the locked position holds at most that many.

(iii) In a constant-product pool, a full-range position with liquidity L that holds T tokens implies the price (L / T)². Combining (i) and (ii): P(τ) ≥ L0² / (TL + U(τ))² = EL · TL / (TL + U(τ))² ≥ p · TL² / (TL + U(τ))², using EL ≥ p · TL from Proposition 4. ∎

The pool price can never fall below 24.75% of the window price
Worst case: every unlocked token sold at once, nobody buying. % of window price p
computed from formula (7) · TL = 495,000,000, So = 500,000,000, 24-hour unlock

The bound is a worst case: every unlocked token sold, nobody buying. Swap fees only lift the price above it. One minute after the market opens, the largest possible coordinated dump moves the price by 0.14%; after one hour, by at most 7.9%. Exact values are in Appendix B.

Corollary 5.1 (Permanent price floor). For τ ≥ V, U(τ) = So, so at all times after settlement:

P  ≥  F=p⋅(TLTL+So)2=p⋅(495995)2≈0.2475 pP \;\ge\; F = p \cdot \left( \frac{T_L}{T_L + S_o} \right)^{2} = p \cdot \left( \frac{495}{995} \right)^{2} \approx 0.2475\,p
(8)

The pool therefore always holds enough WETH to buy any token offered to it at a marginal price of at least F, and any holder can always sell into it at no less than F per token, minus the 0.3% swap fee. This is a property of the Blindfair pool, denominated in ETH. It says nothing about the token’s value in dollars or about prices on other venues, and it holds only if the contracts are correct (§12).

Both bounds are the same for every launch. Since TL = (1 − f) · So, they depend only on the fee and on the share of the unlock elapsed, not on the raise or the split (Appendix B). Without the fee, the floor would be exactly a quarter of the window price.

Proposition 6 (Address exclusivity). No party other than the factory can deploy code at a Blindfair token address.

Proof. By (2), the address is determined by the deployer, σ and the init code hash. A contract deployed by any other deployer has a different address unless a keccak-256 preimage is found, which is computationally infeasible. ∎

Proposition 7 (Creation non-front-runnability). No party can make the factory deploy at the address another creator expects.

Proof. By (1), σ includes the caller’s address. A copied createLaunch transaction submitted by another address uses that address in σ, and therefore deploys at a different address. ∎

Proposition 8 (No pre-settlement market). Before settlement, no address other than the factory holds tokens of a launch, so no market for the token can exist.

Proof. The token mints S to the factory in its constructor and has no other mint path. The factory transfers tokens only in settle (to the pair and to DEAD) and in claim and claimFor, which require settlement. The pair exists from creation, but adding liquidity requires tokens, so nobody can seed it or trade in it before settlement.

A party can donate WETH to the empty pair. The donation is included in the pool’s ETH reserve at settlement, which raises the opening price above p at the donor’s expense, and is then locked with the burned liquidity forever. Participants gain; the donor loses. ∎

Proposition 9 (Conservation). For a settled launch, every token and every wei is accounted for:

S=∑iai+ra+TL+(SL−TL)C=EL+φc+φpS = \sum_i a_i + r_a + T_L + (S_L - T_L) \qquad\qquad C = E_L + \varphi_c + \varphi_p

where ra is the allocation rounding residue.

Proof. Σ ai + ra = So by (4) and the definition of ra. TL + (SL − TL) = SL, and So + SL = S. For ETH, EL = C − φ and φ = φc + φp by §6.6. ∎

For a failed launch: S is burned, and C = Σ ci is refundable in full.

Proposition 10 (Liveness). Every launch reaches a terminal state, and every participant can obtain their tokens or their ETH, without any specific party’s cooperation.

Proof. settle, claim, claimFor and refund are callable by anyone under conditions that depend only on time and state. No function requires a signature or action from the creator, the developer or any designated address. ∎

Proposition 11 (Self-funding is unprofitable). A creator who contributes x to their own window receives exactly what any participant contributing x receives, and recovers only half of the fee that contribution generates: the round trip costs x · f / 2.

Proof. The contribution raises C by x and therefore the fee by x · f, of which the creator recovers x · f / 2 as creator share. Their tokens are bought at p like everyone else’s and unlock on the same schedule. Net, they pay x · f / 2 for no privileged position. ∎

9. Incentives and market dynamics

9.1 No reason to rush

By Proposition 1, priority fees, private order flow and bundles buy nothing during the window. A rational bot has no reason to pay more than the minimum gas to be included. Gas wars at launch disappear.

9.2 A reason to wait, and its limits

Since contributions are public in the current version, a participant who waits learns more about total demand. One equilibrium is that many participants contribute late. Three things bound this effect:

  • No price advantage. The late participant pays p, like everyone else.
  • Incomplete information. Others can still contribute after you, so nobody knows the final C until the close.
  • Execution risk. Transactions landing in a block whose timestamp is at or after te revert. Waiting until the last seconds risks missing the window entirely.

The application warns participants during the last minute. A randomized close, where the exact last block is not known in advance, is under research (§18.1).

9.3 Price-taking contributions

Contributions carry no limit price. A participant who contributes 1 ETH expecting a low price may end up paying a high one if demand is strong. This is the main risk for participants and the main difference between the window and a classic batch auction. The application shows, at every moment, the price the window would clear at if it closed now. The guidance is simple: contribute an amount you are comfortable with at any plausible price. Limit contributions are a research item (§18.2).

The price you see is your best case. If the window holds Cnow when you contribute x, your allocation is at most So · x / (Cnow + x), reached only if nobody contributes after you; every later contribution lowers it. The application shows this figure before you confirm.

9.4 The window versus the open market

For the same ETH, the window gives more tokens than the pool right after it. In a launch that raised 20 ETH, a buyer who skips the window and spends 1 ETH in the pool right after settlement receives about 23.7 million tokens, against 25 million in the window: 5.1% fewer. With 5 ETH, 99.6 million against 125 million: 20.4% fewer. The pool charges price impact and the swap fee; the window charges neither.

The trade-off is liquidity. Window tokens unlock over 24 hours; tokens bought in the pool are free at once. The window is the cheap entry, the pool is the liquid one.

9.5 After settlement: a market, not a window

Once the pool is live, Blindfair’s guarantees about ordering no longer apply. The first buyers after settlement face a constant-product curve, and the first of them get the lowest market prices. Bots can back-run the settlement transaction, or call settle themselves to be first in line.

Four facts limit the harm:

  • The first buyers pay at least p. The pool opens at p or above (Proposition 4), and nothing is unlocked in the settlement block, so the price cannot fall below p there (Proposition 5 at τ = 0).
  • Sales are bounded. The price can fall below p only through sales of unlocked or bought tokens, bounded at every moment by Proposition 5.
  • The floor holds. Whatever happens, the pool price stays above F ≈ 0.2475 p (Corollary 5.1).
  • The fair entry was open to all. Anyone who wanted the window price had ten minutes to get it.

The window is the fair entry. The market is a market. A decaying swap fee in the first blocks after settlement is under research (§18.3).

9.6 Concentration

Allocation is proportional to contribution. A participant who contributes half the total receives half of So, which is a quarter of the supply. Uniform pricing makes this fair in price, but not necessarily diverse in distribution. The unlock bounds how fast a large holder can sell, not how much they hold. Because contributions are public before phase 3, concentration is visible live, and the application displays it: top contributors’ share, number of contributors and the distribution so far.

9.7 Creator incentives

Creators receive half the fee, in ETH, proportional to the raise. A creator is paid for bringing demand, not for holding supply. A failed launch pays the creator nothing and costs them the gas of deploying a token and a pair. A creator who wants tokens buys them in the window at the public price, under the public unlock.

Spam launches cost gas and earn nothing unless real participants contribute. The protocol does not curate launches. The application may sort and filter them; any other interface can make different choices.

9.8 Fake demand and wash contributions

A contribution is real, final ETH. Someone who inflates the total to attract others pays the same price as them and cannot withdraw. Fake demand on Blindfair is simply demand.

9.9 Summary of strategies

StrategyTypical launchBlindfair
Buy in the first blockLowest priceSame price as everyone
Spread across many walletsBypass caps, hide sizeNo effect
Pay priority feesBetter positionWasted gas
Sandwich early buyersProfit from price impactNo price impact in the window
Fake demand, then withdrawPossible on some platformsContributions are final
Sell the whole bag at openCommon0.07% after one minute of trading
Delay settlement to open with unlocked supplyNot applicableUnlock starts at settlement
Skip the window, buy the openCheapest if fastFewer tokens than the window for the same ETH
Pull liquidityPossible if LP heldLP burned
Wait until the endUsually pointlessInformation, not price; risk of missing the close

10. Privacy architecture

This section specifies phase 3. It is a design, not a live feature. Private contributions ship with a new factory version; launches created on earlier factories are unaffected.

10.1 Privacy threat model

Assume an adversary who sees everything public: every transaction, every event, the mempool and the full state of every contract. Assume they may also run relayers, run an RPC endpoint the user connects to, or run a copy of the application. The adversary does not control the user’s device.

10.2 Goals and non-goals

Goal. For a successful launch, an observer cannot determine which depositing address corresponds to which receiving address, beyond what the anonymity set allows.

Non-goals in phase 3.

  • Hiding that an address participated in a launch. Depositors are public; phase 4 addresses this.
  • Hiding the total raised or the number of notes.
  • Protecting users from leaks they create themselves (§10.16).
  • Providing private refunds for failed launches (§10.14).

10.3 Notes

A note is a fixed-denomination contribution attached to a commitment:

cm=H(s,ν)cm = H(s, \nu)
(9)

s (secret) and ν (nullifier) are random field elements generated on the user’s device. They never leave it, except in a public exit (§10.9). H is the Poseidon hash [5], chosen for efficiency inside zero-knowledge circuits.

10.4 Denominations

Notes come in three denominations: D ∈ {0.1, 1, 10} ETH. An arbitrary amount such as 3.1847 ETH is a fingerprint. A 1 ETH note is indistinguishable from every other 1 ETH note in the same launch. Larger contributions use several notes. Users should avoid unusual combinations (§10.16).

10.5 Merkle trees

Each launch keeps one incremental Merkle tree per denomination, built with Poseidon. The tree’s depth grows with the number of notes, as in the LeanIMT [11], up to 20 levels (about one million notes), so a launch with a few hundred notes pays for about nine levels per deposit, not twenty. Because deposits are only accepted during the window, each tree is frozen at the close. Its final root RL,D is the only root binding proofs can use. No root history is needed.

10.6 Deposit

During the window, a user calls deposit(L, D, cm) with msg.value = D + g.

The contract checks that the window is open, that D is a valid denomination, that cm is non-zero and unused, and that the sender is not on the sanctions list (§10.13). It then appends cm to the tree TL,D, records the depositor of that leaf, and adds D to C. D counts toward the total exactly like a public contribution. g, a fixed gas allowance per note set at deployment, is held aside: it pays for the bind and gives the receiving address a stipend (§10.10).

10.7 Binding circuit

After settlement, the user’s device produces a zero-knowledge proof π for the following statement.

Private inputs: s, ν, the Merkle path and path indices in TL,D, and the Merkle path in the association set.

Public inputs: the tree root RL,D, the nullifier hash η, the launch L, the denomination D, the recipient r, the relayer ρ, the relayer fee φr and the association set root A.

Constraints:

cm=Poseidon(s,ν)MerkleRoot(cm,path,indices)=RL,Dη=Poseidon(ν,L)MerkleRoot(cm,assocPath,assocIndices)=Arsq=r⋅r,ρsq=ρ⋅ρ,φsq=φr⋅φr\begin{aligned} cm &= \mathrm{Poseidon}(s, \nu) \\ \mathrm{MerkleRoot}(cm, \mathit{path}, \mathit{indices}) &= R_{L,D} \\ \eta &= \mathrm{Poseidon}(\nu, L) \\ \mathrm{MerkleRoot}(cm, \mathit{assocPath}, \mathit{assocIndices}) &= A \\ r_{sq} = r \cdot r, \quad \rho_{sq} = \rho \cdot \rho, \quad \varphi_{sq} &= \varphi_r \cdot \varphi_r \end{aligned}

The last line adds a quadratic constraint on each of r, ρ and φr. Without it, a compiler can drop a public input that no constraint uses, and the proof would then verify for any value of that input. With it, the proof is valid only for the recipient, relayer and fee the user chose: anyone can submit it, nobody can change where the tokens or the fee go.

10.8 Binding on-chain

Anyone, typically a relayer, calls bind(L, D, π, η, r, ρ, φr, A).

The contract checks that the launch is settled, that A is one of the association roots it accepts (§10.12), that η has not been used, that φr ≤ g, and that π verifies. It then marks η spent, pays φr to ρ and the rest of g to r, and credits the note to r’s contribution:

cr←cr+Dc_r \leftarrow c_r + D
(10)

From then on, r’s allocation follows formula (4), and r unlocks and claims exactly like a public participant. The unlock is anchored to settlement, so binding late costs nothing: at bind time, r can already claim everything unlocked so far. This rewards patience, which is also the best privacy practice.

The nullifier is scoped to the launch (η = H(ν, L)). A note belongs to one launch, so this is domain separation: a wallet that reused a secret by mistake would still produce unrelated nullifiers in different launches.

10.9 Public exit

A depositor whose note is in no accepted association set, or who simply prefers it, can always exit publicly by calling bindPublic(L, D, s, ν), which only the address that deposited the leaf cm = H(s, ν) can call.

The contract recomputes cm, checks the depositor, computes η = H(ν, L), checks that η is unspent and marks it spent, credits D to the depositor’s contribution and returns g to them. Revealing s and ν costs nothing, because the exit is public anyway. Spending η is what prevents the same note from being credited twice, once publicly and once through a private bind.

10.10 Relayers and gas

A fresh address holds no ETH, and funding it from a known wallet would recreate the link. Phase 3 solves this in three ways:

  • Relayed binding. Relayers submit bind and receive φr, which the user chooses when proving, from current gas prices. Because r, ρ and φr are bound to the proof, a relayer can only submit or decline, and a front-runner who copies a relayer’s transaction pays the gas while the fee still goes to the relayer named in the proof.
  • Stipend. The rest of g goes to r at binding, so the fresh address can pay for its first transactions.
  • Gasless approvals. The token supports EIP-2612 permits [6], and claimFor lets anyone push tokens to r. Combined with relayed or sponsored swaps, a fresh address can claim and trade without ever being funded from a known wallet.

g is a constant, so it is sized to cover a bind at high gas prices, including the creation of the recipient’s account, which Glamsterdam’s EIP-8037 makes more expensive [9]. Anyone can run a relayer. The application lists several and lets users choose one or submit bind themselves with φr = 0.

10.11 Proving system

Two families are candidates:

  • Groth16: smallest proofs and cheapest on-chain verification, but a circuit-specific trusted setup. If chosen, it will use a public multi-party ceremony, which is secure as long as a single participant is honest.
  • PLONK-family systems with a universal setup: slightly larger proofs and verification costs, no circuit-specific ceremony.

The choice will be made during phase 3 development and published with its rationale. In both cases proofs are generated client-side, in the browser, in a few seconds on ordinary hardware.

10.12 Association sets

Following the association-set construction proposed for Privacy Pools [3], every private bind proves that the note belongs to an association set: a Merkle tree of deposits that an association set provider (ASP) has approved, excluding deposits linked to known illicit sources such as identified hacks. The proof reveals membership in the set, not which member.

ASP roots are published on-chain by an ASP address fixed at deployment. The contract accepts a fixed number of the most recent roots, so a proof built against a recent root does not fail when the ASP updates. An ASP can do exactly one thing: decline to include a deposit in its set, which denies that deposit a private bind. It cannot touch funds. If the ASP stops publishing, private binds stop; funds do not, because every depositor can exit publicly (§10.9). The ASP can deny privacy, never funds.

10.13 Sanctions screening

deposit checks the sender against an on-chain sanctions oracle and rejects sanctioned addresses. This adds a trust assumption: the oracle’s operator can prevent future deposits from an address. It cannot affect existing deposits, allocations or any other function.

10.14 Failed launches

If a launch with private notes fails, each note is refunded, D + g, to the address that deposited it, publicly, without a proof. This is deliberate. Private refunds would turn failed launches into a mixer: deposit notes into a launch designed to fail, then withdraw to fresh addresses. Privacy in Blindfair exists only for receiving tokens from a successful launch, never for moving ETH from one address to another.

10.15 Residual misuse

Any private path from ETH to a tradable asset can be used to move value. A determined actor could deposit notes, bind to a fresh address and sell the tokens. This channel is expensive and slow: it pays the launch fee, bears full price risk, waits through the 24-hour unlock, faces market slippage, and requires inclusion in an association set and passing sanctions screening at deposit. It is a poor laundering tool, and the design aims to keep it one.

10.16 Anonymity and user behavior

The anonymity set of a note is the set of notes of the same denomination in the same launch, excluding those that exited publicly. Nullifiers do not reveal which note was bound, so the binding order does not shrink the set. Timing and behavior can:

  • binding immediately after a window with few notes;
  • sending tokens from r back to the depositing address, or to an address linked to it;
  • depositing an unusual combination of notes (for example, seven 0.1 ETH notes);
  • choosing an unusual relayer fee, or the same unusual fee across launches;
  • using the same IP address, browser profile or RPC endpoint for depositing and binding;
  • trading from r in patterns that mirror the depositor’s history.

The application displays the anonymity set of each denomination before deposit and before bind, suggests standard fees, and recommends waiting.

10.17 What remains public in phase 3

InformationStatus
Total raised and number of notes per denominationPublic
Depositing addresses and their denominationsPublic
Each bind’s receiving address, relayer, fee and allocationPublic
Public exits, with their addresses and notesPublic
Association set rootsPublic
Which depositor owns which noteHidden
Which receiving address corresponds to which depositorHidden
Which member of an association set a proof refers toHidden

10.18 Phase 4: shielded balance

The next step is a shielded balance: users deposit into a single pool at any time, unrelated to any launch, and later contribute privately to any window from that balance. That would hide participation itself, not only the link to the receiving address. It requires larger circuits, a global association framework and a separate audit, and is listed as research.

11. Smart contract architecture

11.1 Contracts

ContractPurposeUpgradeableOwner
BlindfairFactoryCreation of tokens and pairs, windows, settlement, liquidity, allocations, claims, refunds, feesNoNone
BlindfairTokenFixed-bytecode ERC-20 with EIP-2612 permitsNoNone
UniswapV2PairMarket, created by the factory at launch through the canonical Uniswap v2 factoryNoNone (protocol fee controlled by Uniswap governance)
Phase 3: BlindfairPrivateFactory, Verifier, Poseidon Merkle treeNotes, proofs, binding, public exitsNoNone (ASP and sanctions oracle fixed at deployment)

11.2 Factory interface

interface IBlindfairFactory {
    enum State { NONE, OPEN, CLOSED, SETTLED, FAILED }
    // creation
    function createLaunch(string calldata name, string calldata symbol)
        external returns (address token, address pair);
    function predictToken(address creator, uint256 nonce)
        external view returns (address);
    function nonces(address creator) external view returns (uint256);
    function isLaunch(address token) external view returns (bool);
    // window
    function contribute(address token) external payable;
    // settlement
    function settle(address token) external;
    // after settlement
    function claim(address token) external;
    function claimFor(address token, address user) external;
    function claimMany(address[] calldata tokens) external;
    // failure
    function refund(address token) external;
    // fees
    function withdrawCreatorFees() external;
    function withdrawProtocolFees() external;
    // views
    function state(address token) external view returns (State);
    function launchInfo(address token) external view returns (
        address creator, address pair,
        uint64 start, uint64 end, uint64 settledAt,
        uint256 raised
    );
    function contributed(address token, address user) external view returns (uint256);
    function allocation(address token, address user) external view returns (uint256);
    function unlocked(address token, address user) external view returns (uint256);
    function claimable(address token, address user) external view returns (uint256);
    function floorPrice(address token) external view returns (uint256 weiPerToken);
    function creatorFees(address creator) external view returns (uint256);
    function protocolFees() external view returns (uint256);
}

11.3 Events

event LaunchCreated(address indexed token, address indexed creator, address pair,
                    string name, string symbol, uint64 start, uint64 end);
event Contributed(address indexed token, address indexed user,
                  uint256 amount, uint256 totalRaised);
event Settled(address indexed token, uint256 raised, uint256 lpEth,
              uint256 lpTokens, uint256 burned, uint64 settledAt);
event Failed(address indexed token, uint256 raised);
event Claimed(address indexed token, address indexed user, uint256 amount);
event Refunded(address indexed token, address indexed user, uint256 amount);
event CreatorFeeCredited(address indexed creator, address indexed token, uint256 amount);
event FeesWithdrawn(address indexed to, uint256 amount);

Every state change emits an event, so any indexer can reconstruct the full history of every launch.

11.4 Errors

UnknownLaunch, WindowClosed, WindowOpen, AlreadySettled, NotSettled, NotFailed, NothingToClaim, NothingToRefund, NothingToWithdraw, ZeroAmount, TransferFailed, InvalidName, InvalidSymbol.

11.5 Reference pseudocode

createLaunch(name, symbol):
    require 0 < len(name) ≤ MAX_NAME and 0 < len(symbol) ≤ MAX_SYMBOL
    σ = keccak256(abi.encode(msg.sender, nonces[msg.sender]))
    nonces[msg.sender] += 1
    pending = (name, symbol)
    token = CREATE2(σ, BlindfairToken.initCode)        // mints S to the factory
    delete pending
    pair = uniV2.getPair(token, WETH)
    if pair == 0: pair = uniV2.createPair(token, WETH)  // may already exist (§6.3)
    launches[token] = { creator: msg.sender, start: now, state: OPEN,
                        pair, settledAt: 0, raised: 0 }
    emit LaunchCreated(...)                              // end = start + Δ, never stored
contribute(token):
    L = launches[token]
    require L exists and now < L.start + Δ and msg.value > 0
    positions[token][msg.sender].contributed += msg.value
    L.raised += msg.value
    emit Contributed(...)
settle(token):
    L = launches[token]
    require now ≥ L.start + Δ and L.state == OPEN
    if L.raised < C_MIN:
        L.state = FAILED
        emit Failed(...)
        token.transfer(DEAD, S)
        return
    L.state = SETTLED ;  L.settledAt = now
    φ   = L.raised * 100 / 10_000
    φc  = φ / 2 ;  φp = φ − φc
    E_L = L.raised − φ
    T_L = S_o * E_L / L.raised
    creatorFees[L.creator] += φc ;  protocolFees += φp   // effects before interactions
    emit CreatorFeeCredited(...) ;  emit Settled(...)
    token.transfer(DEAD, S_L − T_L)
    WETH.deposit{value: E_L}()
    WETH.transfer(L.pair, E_L)
    token.transfer(L.pair, T_L)
    IUniswapV2Pair(L.pair).mint(DEAD)
claimFor(token, user):
    L = launches[token] ;  P = positions[token][user]
    require L.state == SETTLED
    a = S_o * P.contributed / L.raised
    u = a * min(now − L.settledAt, V) / V
    amount = u − P.claimed
    require amount > 0
    P.claimed = u
    emit Claimed(...)
    token.transfer(user, amount)
refund(token):
    require launches[token].state == FAILED
    P = positions[token][msg.sender]
    amount = P.contributed
    require amount > 0
    P.contributed = 0
    emit Refunded(...)
    msg.sender.call{value: amount}("")                 // reverts with TransferFailed on failure

The stored state stays OPEN until settlement; state() reports CLOSED when now ≥ end and the launch is not yet settled or failed. floorPrice returns F from formula (8), computed from the stored raise.

11.6 Access control

In the current version there is none. No function checks msg.sender against a privileged address, except fee withdrawals, which pay only the caller’s own credited balance. There is no owner, no role, no pause, no proxy, no selfdestruct, no delegatecall to mutable code.

Phase 3 adds two narrow roles, both fixed at deployment: the ASP address, which can only publish association roots, and the sanctions oracle, which deposit reads. Neither can move funds, pause a launch or change a parameter.

11.7 External calls and reentrancy

External calls go only to the token (whose code is fixed and known), WETH, the Uniswap v2 factory and pair, and ETH recipients in refunds and fee withdrawals. All state changes happen before external calls, and every state-changing function is protected by a reentrancy guard.

11.8 Gas

Every transaction shows its own gas cost on-chain. Sepolia has run the Glamsterdam upgrade since 6 October 2026 [10], ahead of its mainnet activation. Glamsterdam’s EIP-8037, scheduled for mainnet, raises the cost of creating new state: deploying the token and the pair, a first contribution (a new storage slot), a first claim (a new token balance) and the stipend’s new account in phase 3 [9].

Design choices that reduce gas: lazy allocation computation (no loop over participants), a single factory holding all launches, packed storage per launch, pair creation at launch rather than at settlement, and claimMany for batching.

11.9 Token contract

Every launch of a factory version deploys the same creation code, so the token source is verified once and every launch can be matched to it (§15.3).

  • Standard ERC-20 with 18 decimals: transfer, transferFrom, approve, allowance, balanceOf, totalSupply.
  • EIP-2612 permit [6], with a domain separator that includes the chain id.
  • The constructor reads the name and symbol from the factory, records the factory address and mints S to the factory. There is no other mint path.
  • No owner, no admin, no fee on transfer, no blacklist, no pause, no transfer hooks, no upgrade.
  • Burning is a transfer to DEAD, so totalSupply always reads 1,000,000,000, while at most 995,000,000 tokens can ever circulate (§15.4).

11.10 Storage layout

Each launch uses three storage slots:

SlotFieldsBytes used
1creator (address), start (uint64), state (uint8)29
2pair (address), settledAt (uint64)28
3raised (uint128)16

The window end, start + Δ, is computed rather than stored. A uint128 holds far more than all the ETH that exists: about 1.2·10²⁶ wei, against a limit of 3.4·10³⁸.

Each participant uses one slot per launch, holding contributed and claimed as two uint128 values. A first contribution creates that slot; claims only update it. Since EIP-8037 prices new state separately from execution [9], this keeps the state a participant creates to one slot per launch, plus their token balance at the first claim.

12. Security analysis

12.1 Trust assumptions

Blindfair relies on:

  • Ethereum consensus, including post-Merge slot timestamps;
  • the Uniswap v2 core contracts and the canonical WETH contract;
  • Uniswap governance, for one parameter only: the v2 protocol fee, on since December 2025, which takes 1/6 of swap fees and cannot touch pool principal [7, 8];
  • the Solidity compiler;
  • the OpenZeppelin ERC-20 implementation;
  • in phase 3: the soundness of the proving system, the Poseidon hash, the trusted setup if one is used, the association set provider (for privacy, not funds) and the sanctions oracle (for deposits, not funds).

It does not rely on any operator, keeper, multisig, Blindfair governance process or off-chain server.

12.2 Adversaries

AdversaryStrategyOutcome
SniperBuy in the creation blockSame price as the last block of the window (P1)
BundlerBuy from many addresses at creationSame price, same unlock (P1, P2)
Sandwich botWrap window contributionsNo price curve in the window, nothing to extract
CopycatReplay a creator’s createLaunchDifferent salt, different address (P7)
SquatterDeploy at a future token addressOnly the factory can (P6)
Pair squatterCreate the pair before the launch to make createLaunch revertThe factory uses the existing pair (§6.3)
Pool seederSeed the pair at a chosen priceNo tokens exist to seed it (P8)
DonorSend WETH to the empty pairRaises the opening price at their own expense (P8)
Fake demandDeposit, then withdraw before closeContributions are final
DelayerDelay settlement so the market opens with unlocked supplyUnlock starts at settlement (§6.8)
DumperSell the full allocation at open0.07% sellable one minute after the market opens (P5)
Crash to zeroSell every token into the poolThe price cannot fall below 24.75% of p (Corollary 5.1)
RuggerWithdraw liquidityLP burned, no admin path
Malicious creatorMint, tax, blacklist, pauseNo such functions exist
Absent creatorNever settleAnyone can settle, claim or refund (P10)
Block proposerStretch or shrink the windowTimestamps are fixed by the slot; a proposer can only include or exclude transactions
Censoring builderExclude contributionsMust control 50 consecutive slots to censor a full window
Fee recipientBlock settlementFees are pull-based; a failing recipient affects only itself
Relayer (phase 3)Redirect a bind or its feeRecipient, relayer and fee are bound to the proof (§10.7)
Mempool copier (phase 3)Resubmit a relayer’s bindPays the gas; the fee still goes to the named relayer
Double exit (phase 3)Exit publicly, then bind the same note privatelyThe public exit spends the note’s nullifier (§10.9)
Phase 3 launderingPrivate path from ETH to a fresh addressNo private refunds; association sets; sanctions screening; fee, unlock and price risk (§10.14–10.15)

12.3 Residual risks

Last-block information. A participant or the final block’s proposer can contribute knowing the total raised so far. They pay p. Their advantage is information, not price.

Censorship. A builder can exclude contributions from its blocks. Censoring an entire window requires a run of colluding builders across 50 slots.

Post-settlement ordering. The first market buyers after settlement race each other (§9.5). Searchers can bundle the settlement transaction with their own purchase to be first in line. They pay p or more, since nothing is unlocked in the settlement block, and their purchase raises the price for whoever follows. Later buyers face the usual AMM risks, sandwiches included, and should set slippage limits. Window participants are unaffected: their price was fixed at the close.

External governance. Uniswap governance can change the v2 protocol fee on every v2 pool, Blindfair pools included. It can redirect up to 1/6 of fee income, nothing else.

Smart contract bugs. No administrator can rescue funds. Testing (§12.5) reduces that risk; nothing removes it.

Front-end compromise. A malicious interface could ask users to sign harmful transactions. Mitigations are in §12.6.

Impersonation. Anyone can launch a token named after a famous asset. The protocol cannot prevent it. The application warns.

12.4 Invariants

The following must hold at all times and will be enforced by invariant tests:

  1. No tokens of a launch are held outside the factory before settlement.
  2. For every settled launch, Σ claimed_i ≤ So.
  3. For every settled launch, the factory’s balance of that token is at least Σ (ai − claimed_i).
  4. The factory’s ETH balance is at least the sum of: the raise of every launch not yet settled or failed, refundable contributions of failed launches, unwithdrawn creator and protocol fees, and, in phase 3, unpaid gas allowances.
  5. State transitions are monotonic: OPEN → SETTLED or OPEN → FAILED, never back.
  6. Contributions only increase raised while now < end.
  7. At settlement, the pool’s price is at least raised / So, and equal to it within rounding unless WETH was donated (P4, P8).
  8. LP tokens minted at settlement are held only by DEAD, plus the 1,000 units Uniswap locks at address zero.
  9. For every settled launch, the locked position’s liquidity never falls below L0, with the Uniswap protocol fee switched on (P5, step i).
  10. In phase 3, each nullifier is spent at most once, by bind or by bindPublic.

12.5 Testing

The contracts were tested on testnet before the mainnet launch. For this release and any later one, testing must establish:

  1. every function and every edge case of §6.13, unit by unit;
  2. correct behaviour against the live Uniswap v2 and WETH contracts on a mainnet fork, with the Uniswap protocol fee switched on;
  3. correct allocation, unlock and fee arithmetic under randomized contributions, timings, settlement delays and raise sizes;
  4. the invariants of §12.4, including the floor of Corollary 5.1, under random sequences of trades;
  5. a source verified on Etherscan, with the compiler version and settings published.

Phase 3 ships as a separate factory version, with a public trusted-setup ceremony if its proving system needs one.

12.6 Operational security

  • The application is static and open source. Each release’s content hash is published, so users can verify they run the published code.
  • Contract addresses are published only on the official X account, @Blindfair, and in the application.
  • Official announcements are signed with a key published at genesis, so the community can verify authenticity even if a social account is compromised.
  • The project never asks for private keys or seed phrases, never DMs first and never runs presales or whitelists.

13. Economics

13.1 Supply of every launch

AllocationTokensShareDestination
Opening allocation500,000,00050%Window participants, pro rata, unlocked over 24h from settlement
Liquidity495,000,00049.5%Uniswap v2 pool, LP burned
Burned at settlement5,000,0000.5%Burn address
Creator, team, presale, partners, treasury00%None

13.2 Worked examples

SmallMediumLarge
Total raised1.5 ETH20 ETH300 ETH
Window price per token0.000000003 ETH0.00000004 ETH0.0000006 ETH
Tokens per ETH333,333,33325,000,0001,666,667
Fee (1%)0.015 ETH0.2 ETH3 ETH
Creator reward0.0075 ETH0.1 ETH1.5 ETH
Protocol share0.0075 ETH0.1 ETH1.5 ETH
ETH in the pool1.485 ETH19.8 ETH297 ETH
Tokens in the pool495,000,000495,000,000495,000,000
Pool opening price0.000000003 ETH0.00000004 ETH0.0000006 ETH
Permanent floor price (24.75%)0.000000000742 ETH0.0000000099 ETH0.0000001485 ETH
Supply excluding burned tokens995,000,000995,000,000995,000,000
Fully diluted value at open2.985 ETH39.8 ETH597 ETH
ETH that doubles the price right after the open0.62 ETH8.2 ETH123 ETH

The last row includes the 0.3% swap fee: doubling the price takes about 41.5% of the ETH in the pool, whatever the raise.

A participant in the medium launch. Alice contributes 0.5 ETH out of 20 ETH, which is 2.5% of the window. Her allocation is 12,500,000 tokens.

Time after settlementAlice can claim, in total
1 minute8,680.56
1 hour520,833
12 hours6,250,000
24 hours12,500,000

Alice paid 0.00000004 ETH per token, exactly what a bot paid in the first block and what someone paid in the last second. Whatever happens next, the pool will always buy her tokens at no less than 0.0000000099 ETH each, minus the swap fee.

13.3 Fees

FeeAmountRecipient
Launch fee1% of the raise, at settlementHalf creator; half protocol, of which half to project token holders
Failed launchNoneRefunds are complete
Transfer taxNoneNot applicable
Claims and refundsGas onlyNot applicable
Private binding (phase 3)Fixed gas allowance g per noteRelayer fee chosen by the user; the rest to the recipient as a stipend
Uniswap swap fee0.3% per swap0.25% to liquidity providers, including the burned position, forever; 0.05% to the Uniswap protocol while its fee switch is on [7]

13.4 Use of protocol revenue

Half of the protocol share, 0.25% of each raise, goes to holders of the project token in ETH (§13.5). The other half funds, in order: security work, including audits and bug reports; infrastructure (application hosting, relayer bootstrapping); the development of phase 3; and research. None of this is a promise of yield: fees exist only when launches raise ETH.

13.5 The project token

The project token launches alongside the launchpad, on Ethereum mainnet, in a Uniswap v4 pool. It is not created by the Blindfair factory, and it is not a Blindfair launch.

PropertyValue
Chain and venueEthereum mainnet, Uniswap v4
Supply placed in the pool at launch100%
Team allocation, presale, private roundNone
Liquidity positionSent to a dead address at launch; it can never be withdrawn
Holders’ share of protocol fees0.25% of every raise on Blindfair, paid in ETH
Contract addressCA, published on the official X account only
Launch dateDATE

Why it exists. Blindfair earns one fee: 1% of each raise. Half goes to the creator of the launch. The other half is the protocol share, and half of that, 0.25% of every raise, goes to holders of the project token, in ETH. People who back the project share in what the launchpad earns, in proportion to what they hold.

Why it is not launched on Blindfair. The factory has no special path for anyone, its developer included, and that is deliberate. Launching the project token through it would make me the creator of that launch, collecting its creator fee and choosing its timing: the first launch on Blindfair would be its developer’s own. Launching it separately keeps every launch on the factory free of insiders and keeps the two systems independent. A bug in the factory cannot touch the token, and the token’s market cannot affect any launch.

How the fee share works. The factory credits the protocol share of each raise, 0.5%, to the protocol fee recipient (§6.11). Half of it is distributed in ETH to holders of the project token, pro rata to their holdings, excluding the pool and burn addresses. The other half funds the project (§13.4). Each distribution is an on-chain transaction, announced on the official X account. Anyone can check the amount: it is 0.25% of the sum of raised over the factory’s Settled events since the previous distribution.

What it is not. It carries no vote and no control: the launchpad has nothing that can be changed (§14.1). It has no claim on the creator share, on any launch’s pool, or on anything the factory holds. The holders’ share is an operating commitment paid by the fee recipient, not a rule enforced by the factory’s code. Its size depends entirely on launchpad activity: without raises there are no fees, and nothing here promises a return.

14. Governance, team and immutability

14.1 No governance

Blindfair has no owner, no administrator, no multisig, no DAO, no pause, no proxy and no fee switch of its own. Every parameter is a compile-time constant. There is nothing to vote on, because there is nothing that can be changed. The only governance that touches a Blindfair pool is Uniswap’s, through the v2 protocol fee (§6.7).

14.2 The cost of immutability

A bug cannot be patched in place. A correction requires deploying a new factory and announcing it on the official X account. Launches created by an earlier factory continue under the rules they were created with, forever. I prefer a system that nobody can fix to one that somebody can change.

14.3 Versions

Each factory version is a separate, immutable deployment with its own address, its own verified source and its own documentation. The application shows which version every launch uses. Phase 3 (private contributions) is a new version; it does not modify launches made on earlier factories.

14.4 Team

Blindfair is built by an independent developer, under a pseudonym. There is no team allocation, no investor, no advisor and no presale. The design makes my identity irrelevant to your safety: there is no key, role or function through which I, or anyone else, could affect a launch. The only address tied to the project is the protocol fee recipient, which can withdraw credited protocol fees and nothing else; half of what it withdraws goes to holders of the project token (§13.5). Trust the verified code and the on-chain state, not me.

15. Application layer and how to verify a launch

The application is a convenience, not a dependency. Every action is available directly through the contracts, for example from a block explorer.

15.1 Principles

  • Static, open source, reproducible builds.
  • Hosted on content-addressed storage, with each release’s hash published.
  • No backend, no accounts, no analytics, no cookies, no third-party scripts or fonts.
  • Reads chain state through the user’s own RPC when configured.

15.2 Features

  • Launch page: live total raised, number of contributors, concentration, time remaining, the price the window would clear at if it closed now, and the floor that price implies.
  • Verification badge: shown only if isLaunch(token) returns true on an official factory. Tokens from elsewhere display a warning.
  • Impersonation warnings for tickers and names resembling well-known assets.
  • Last-minute warning in the final minute of a window.
  • Settle button on any closed, unsettled launch.
  • Creator tools: predicted next token address, launch announcement helper.
  • Unlock view: allocation, unlocked, claimed and claimable, with batch claiming.
  • Phase 3: note management, anonymity set display, relayer choice, client-side proving.

15.3 Verify a launch yourself

Every claim in this paper can be checked from a block explorer, without trusting the application:

  1. It is a Blindfair launch. On the official factory, isLaunch(token) returns true. A token from anywhere else is not a Blindfair token, whatever its name.
  2. The token is the standard token. Its code matches the verified BlindfairToken source of that factory version, like every launch’s: no hidden mint, tax or blacklist.
  3. The window was clean. launchInfo(token) gives start, end and raised. The Contributed events sum to raised, and no token transfer left the factory before the Settled event.
  4. The liquidity is locked. In the settlement transaction, the pair’s LP tokens were minted to 0x…dEaD, plus 1,000 units to address zero.
  5. The price started where it should. Right after settlement, the pair’s reserves give a price of at least raised / 500,000,000.
  6. Your position. allocation, unlocked and claimable return your numbers.
  7. The floor. floorPrice(token) returns F, which is also raised / 500,000,000 × (495/995)².

15.4 What explorers and screeners show

Holder lists, bubble maps and token scanners read a Blindfair launch differently from an ordinary token. What they show is expected:

What you seeWhy
The factory holds up to 50% of the supplyUnclaimed opening allocations. The factory is a contract with no owner; tokens leave it only through claims, to the participants they belong to (§6.9, §11.6)
The pair holds about 49.5%The locked pool (§6.7)
0x…dEaD holds 5,000,000 tokens and the LP tokensThe settlement burn and the burned liquidity
Total supply of 1,000,000,000Burned tokens stay counted; at most 995,000,000 can ever circulate
Many wallets received tokens from the same addressEvery claim is paid by the factory; this is not a bundle
No owner, no mint, no tax, no blacklistTrue of every Blindfair token (§11.9)

Unclaimed tokens stay in the factory until their owner claims them, possibly forever. They are never redistributed.

15.5 Alternative interfaces

Anyone can build another interface on Blindfair. The protocol does not depend on, endorse or restrict any interface, including its own.

16. Compliance considerations

This section describes design choices. It does not claim any particular legal classification for Blindfair in any jurisdiction.

  • No discretionary control of funds. No person can move user funds. Only the contract rules can, and they are public and immutable.
  • No curation. The protocol does not select, review or endorse tokens. Creators are responsible for what they launch.
  • Sanctions. Phase 3 deposits are screened against an on-chain sanctions oracle. The application will not serve sanctioned jurisdictions.
  • Privacy within limits. Association sets, public refunds for failed launches and the economic cost of the private path are designed to make Blindfair a poor tool for laundering (§10.12–10.15).
  • Revenue share. Paying part of the protocol fees to holders of the project token (§13.5) can bring that token under securities or investment rules in some jurisdictions. This paper makes no claim about its legal status.
  • User responsibility. Rules for token launches and privacy software differ by jurisdiction and are changing. Users are responsible for complying with the laws that apply to them, including tax.

17. Limitations

  • Fair is not profitable. Blindfair guarantees how a price is formed, not what it will be. Most tokens, on any platform, lose most of their value.
  • The floor is not a promise of value. It is denominated in ETH, applies to the Blindfair pool, sits 75.25% below the window price, and holds only if the contracts are correct (Corollary 5.1).
  • Price-taking. Contributions have no limit price. A participant can pay more per token than they expected if demand is high (§9.3).
  • Information at the close. Late participants see more of the total (§9.2).
  • The market after the window. Post-settlement trading is an ordinary AMM market, with its usual ordering games and MEV (§9.5).
  • Settlement timing. The market and the unlock start when someone calls settle. Searchers and the application make this fast in practice, but nothing forces a specific block.
  • Concentration. Proportional allocation lets large contributors hold large shares (§9.6).
  • Mainnet gas. Every contribution and claim pays layer-1 gas, which weighs on small participants, and state-creating operations will cost more once Glamsterdam reaches mainnet (§11.8).
  • External dependencies. Uniswap governance controls the v2 protocol fee on Blindfair pools (§6.7); phase 3 adds an association set provider and a sanctions oracle; and the holders’ share of protocol fees is paid by the fee recipient, not by the factory’s code (§13.5).
  • No privacy before phase 3, and partial privacy in phase 3. Depositors are public, and user behavior can undo the rest (§10.2, §10.16).
  • Impersonation. Tickers are not unique; anyone can launch a token with a misleading name.
  • Immutability. Bugs cannot be patched in place (§14.2).
  • Regulatory uncertainty. The legal treatment of launch platforms and privacy software is unsettled in many jurisdictions.
  • Contract risk. Audits reduce it. Nothing removes it.

18. Research directions

18.1 Randomized close

The window would end at the first block after t0 + 9 minutes whose prevrandao satisfies a condition, giving an expected close near ten minutes but an unpredictable last block. Waiting until the end would then risk missing the window. The randomness can be biased by a proposer willing to forfeit a block, and this cost must be weighed against the information it protects.

18.2 Limit contributions

A participant would specify a maximum price. At settlement, if p exceeds it, the part of their contribution above the limit is refunded. The difficulty is that refunds change C, which changes p: the clearing price must be found by an algorithm over sorted limits, as in batch auctions, without unbounded loops on-chain.

18.3 Post-settlement fee decay

With a hook-enabled AMM, the pool could charge a high swap fee in the first blocks after settlement, decaying to the normal fee over a few minutes, with the excess fee added to locked liquidity. This would reduce the value of back-running settlement and would raise the floor over time.

18.4 Scheduled launches

A creator would set a window start time in the future. The address would be known in advance, the community would have time to prepare, and the creator would not need to be present when the window opens.

18.5 Shielded balance

See §10.18.

19. Status

  • Tested. The contracts were tested on testnet before the mainnet launch (§12.5).
  • Live. The launchpad goes live on Ethereum mainnet, with the project token launched alongside it (§13.5).
  • Next. Phase 3, private contributions (Section 10), ships as a new factory version. Phase 4 and the research directions of Section 18 follow, each specified and tested before it ships.

Launches made on a factory keep that factory’s rules forever (§14.2).

20. Developer reference: contracts

This section specifies the factory the way an implementer or an auditor reads it: each external function with its checks, effects, interactions, events and reverts. Every state-changing function holds a reentrancy lock, for example a transient-storage guard (EIP-1153), and follows checks-effects-interactions. Names follow the interface of §11.2.

20.1 Constants and immutables

NameTypeValueNotes
TOTAL_SUPPLYuint2561,000,000,000 × 10¹⁸Minted once, in the token constructor
OPENING_SUPPLYuint256500,000,000 × 10¹⁸So
LIQUIDITY_RESERVEuint256500,000,000 × 10¹⁸SL
WINDOWuint64600Seconds
UNLOCK_PERIODuint6486,400Seconds
FEE_BPSuint256100Out of 10,000
MIN_RAISEuint2561 etherCmin
MAX_NAME, MAX_SYMBOLuint25632, 10Bytes
DEADaddress0x…dEaDReceives burned tokens and the LP tokens
WETHaddress, immutableCanonical WETH9Constructor argument
UNISWAP_V2_FACTORYaddress, immutableCanonical Uniswap v2 factoryConstructor argument
PROTOCOL_FEE_RECIPIENTaddress, immutableCAConstructor argument
TOKEN_INIT_CODE_HASHbytes32, constantkeccak256 of the token creation codeUsed by predictToken

20.2 Storage

struct Launch {
    address creator;    // slot 0
    uint64  start;      // slot 0
    State   state;      // slot 0, uint8
    address pair;       // slot 1
    uint64  settledAt;  // slot 1
    uint128 raised;     // slot 2
}
struct Position {
    uint128 contributed;
    uint128 claimed;
}
mapping(address token => Launch) internal launches;
mapping(address token => mapping(address user => Position)) internal positions;
mapping(address creator => uint256) public nonces;
mapping(address creator => uint256) public creatorFees;
uint256 public protocolFees;

The pending name and symbol exist only while createLaunch runs, in transient storage (EIP-1153) or in storage cleared before the function returns. The window end, start + WINDOW, is computed on read. Slot packing is detailed in §11.10.

20.3 createLaunch

function createLaunch(string calldata name, string calldata symbol)
    external nonReentrant returns (address token, address pair);
  • Checks. 0 < bytes(name).length ≤ MAX_NAME, else InvalidName. 0 < bytes(symbol).length ≤ MAX_SYMBOL, else InvalidSymbol.
  • Effects. salt = keccak256(abi.encode(msg.sender, nonces[msg.sender])); nonces[msg.sender] is incremented; the pending name and symbol are set.
  • Interactions. token = new BlindfairToken{salt: salt}(). The constructor calls back pendingParams() on the factory, a view, and mints TOTAL_SUPPLY to the factory. The pending values are cleared. pair = getPair(token, WETH) on the Uniswap v2 factory, then createPair(token, WETH) if that returns the zero address.
  • Effects. launches[token] = Launch(msg.sender, uint64(block.timestamp), OPEN, pair, 0, 0).
  • Event. LaunchCreated(token, msg.sender, pair, name, symbol, start, start + WINDOW).

The launch record is written after the two deployments because its key, the token address, only exists once CREATE2 has run. Both callees are fixed code: the token’s only callback is a view, and the Uniswap v2 factory is immutable. CREATE2 cannot collide, because the salt contains the caller and their launch count (Proposition 7).

20.4 contribute

function contribute(address token) external payable nonReentrant;
  • Checks. launches[token].start ≠ 0, else UnknownLaunch. block.timestamp < start + WINDOW, else WindowClosed. msg.value > 0, else ZeroAmount.
  • Effects. positions[token][msg.sender].contributed += uint128(msg.value); launches[token].raised += uint128(msg.value).
  • Event. Contributed(token, msg.sender, msg.value, raised).

There is no external call. The uint128 casts cannot truncate: all the ETH in existence is far below 2¹²⁸ wei.

20.5 settle

function settle(address token) external nonReentrant;
  • Checks. The launch exists, else UnknownLaunch. block.timestamp ≥ start + WINDOW, else WindowOpen. state == OPEN, else AlreadySettled.
  • Failure branch. If raised < MIN_RAISE: state = FAILED; Failed(token, raised) is emitted; TOTAL_SUPPLY is transferred to DEAD.
  • Effects. state = SETTLED; settledAt = uint64(block.timestamp); φ = raised × FEE_BPS /10,000; φc = φ / 2; φp = φ − φc; EL = raised − φ; TL = OPENING_SUPPLY × EL /raised; creatorFees[creator] += φc; protocolFees += φp.
  • Events. CreatorFeeCredited(creator, token, φc); Settled(token, raised, EL, TL, LIQUIDITY_RESERVE − TL, settledAt).
  • Interactions. Transfer LIQUIDITY_RESERVE − TL tokens to DEAD; WETH.deposit{value: EL}(); WETH.transfer(pair, EL); token.transfer(pair, TL); IUniswapV2Pair(pair).mint(DEAD).

The pair’s mint measures each deposit as its balance minus its stored reserve, so any WETH sent to the pair beforehand ends up locked in the pool and lifts the opening price (Proposition 8). With an LP totalSupply of zero, mint issues √(EL · TL) − 1,000 LP tokens to DEAD and 1,000 to address zero, and, with the protocol fee on, records kLast [2]. mint reverts on zero liquidity, which cannot happen above MIN_RAISE.

20.6 claim, claimFor, claimMany

function claimFor(address token, address user) external nonReentrant;
function claim(address token) external nonReentrant;      // claims for msg.sender
function claimMany(address[] calldata tokens) external nonReentrant;
  • Checks. state == SETTLED, else NotSettled.
  • Computation. a = OPENING_SUPPLY × contributed / raised; u = a × min(block.timestamp − settledAt, UNLOCK_PERIOD) / UNLOCK_PERIOD; amount = u − claimed, which must be positive, else NothingToClaim.
  • Effects. positions[token][user].claimed = uint128(u).
  • Event. Claimed(token, user, amount).
  • Interaction. token.transfer(user, amount).

All three share one internal function. claimMany skips launches with nothing to claim instead of reverting, so one empty launch cannot block a batch. Every division rounds down, and u reaches a exactly once UNLOCK_PERIOD has elapsed.

20.7 refund

function refund(address token) external nonReentrant;
  • Checks. state == FAILED, else NotFailed. contributed > 0, else NothingToRefund.
  • Effects. contributed = 0.
  • Event. Refunded(token, msg.sender, amount).
  • Interaction. msg.sender.call{value: amount}(""), else TransferFailed.

The call forwards all remaining gas so that smart-contract wallets can receive. The balance is zeroed first and the lock is held, so a reentrant call finds nothing to refund.

20.8 Fee withdrawals

  • withdrawCreatorFees(). Pays creatorFees[msg.sender] to msg.sender, else NothingToWithdraw. The balance is zeroed before the call. Emits FeesWithdrawn(msg.sender, amount).
  • withdrawProtocolFees(). Callable only by PROTOCOL_FEE_RECIPIENT. Pays protocolFees to it the same way.

No ledger reads address(this).balance. ETH forced into the factory, by selfdestruct or as a block’s fee recipient, changes no balance anyone can withdraw and stays there.

20.9 Views

FunctionReturns
state(token)NONE if start = 0; SETTLED or FAILED as stored; CLOSED if block.timestamp ≥ start + WINDOW; otherwise OPEN
launchInfo(token)creator, pair, start, end = start + WINDOW, settledAt, raised
contributed(token, user)The user’s contribution, in wei
allocation(token, user)OPENING_SUPPLY × contributed / raised; during the window, the allocation if the window closed now
unlocked(token, user)0 before settlement; then a × min(now − settledAt, UNLOCK_PERIOD) / UNLOCK_PERIOD
claimable(token, user)unlocked − claimed
floorPrice(token)F in wei per whole token; before settlement, the floor if the window settled now
predictToken(creator, nonce)The CREATE2 address of formula (2), with salt keccak256(abi.encode(creator, nonce))

floorPrice first computes r = TL × 10¹⁸ / (TL + OPENING_SUPPLY), then F = raised × r² /(OPENING_SUPPLY × 10¹⁸). Computing r first keeps every intermediate below about 3·10⁶¹, far from the 2²⁵⁶ limit; the naive order, raised × TL², would overflow.

20.10 Errors

ErrorRaised byCondition
UnknownLaunchcontribute, settleNo launch at this token address
InvalidName,InvalidSymbolcreateLaunchEmpty, or longer than MAX_NAME or MAX_SYMBOL bytes
WindowClosedcontributeblock.timestamp ≥ start + WINDOW
WindowOpensettleblock.timestamp < start + WINDOW
AlreadySettledsettlestate is SETTLED or FAILED
NotSettledclaim, claimForstate is not SETTLED
NotFailedrefundstate is not FAILED
ZeroAmountcontributemsg.value = 0
NothingToClaimclaim, claimForNothing unlocked beyond what was claimed
NothingToRefundrefundNo contribution left
NothingToWithdrawFee withdrawalsNo credited balance
TransferFailedrefund, fee withdrawalsThe ETH transfer reverted

20.11 Call graph and reentrancy

FunctionExternal callsExposureMitigation
createLaunchToken constructor, Uniswap v2 factoryFixed code onlyLock held; the token’s callback is a view
contributeNoneNoneLock held
settleToken, WETH, pairFixed or canonical codeAll effects before the first call; lock held
claim, claimFor,claimManyTokenFixed codeclaimed updated before the transfer
refund, fee withdrawalsArbitrary recipient, via callThe recipient can reenterBalance zeroed first; lock held

20.12 Phase 3 circuit interface (design)

template Bind(DEPTH, ASSOC_DEPTH) {
    // public inputs
    signal input root;            // R_{L,D}, selected by the contract from (L, D)
    signal input nullifierHash;   // η = Poseidon(ν, L)
    signal input launch;          // L
    signal input denomination;    // D
    signal input recipient;       // r
    signal input relayer;         // ρ
    signal input fee;             // φ_r
    signal input assocRoot;       // A
    // private inputs
    signal input secret;          // s
    signal input nullifier;       // ν
    signal input path[DEPTH];
    signal input index[DEPTH];
    signal input assocPath[ASSOC_DEPTH];
    signal input assocIndex[ASSOC_DEPTH];
    // cm = Poseidon(secret, nullifier)
    // MerkleRoot(cm, path, index) === root
    // MerkleRoot(cm, assocPath, assocIndex) === assocRoot
    // Poseidon(nullifier, launch) === nullifierHash
    // recipient, relayer and fee each enter one quadratic constraint
}

DEPTH is the maximum depth of a note tree, 20; shorter trees pad their paths. The verifier contract exposes verifyProof(proof, publicSignals), and bind passes the public signals in the order above.

21. Developer reference: integration

Frontends, wallets, indexers and bots integrate through view calls, events and the Uniswap v2 pair. Nothing requires an API key or a server.

21.1 Reading a launch

  • Discovery. LaunchCreated logs, or isLaunch(token) for a known address.
  • Window. launchInfo gives start and end; raised / OPENING_SUPPLY is the price if the window closed now.
  • Position. contributed, allocation, unlocked and claimable, for any address.
  • Market. The pair’s getReserves, after checking which side is WETH: token0 is the lower of the two addresses.
  • Floor. floorPrice.

21.2 Off-chain formulas

ValueFormula
Price if the window closed now, in wei per tokenraised × 10¹⁸ / OPENING_SUPPLY
Best-case allocation for a user holding c who adds xOPENING_SUPPLY × (c + x) / (raised + x)
Unlocked at time ta × min(t − settledAt, 86,400) / 86,400
Tokens out for x WETHx × 997 × Rtoken / (Rweth × 1,000 + x × 997)
WETH out for y tokensy × 997 × Rweth / (Rtoken × 1,000 + y × 997)
Lowest possible pool price τ seconds after settlementp × (TL / (TL + U(τ)))²

When a result is compared with on-chain values, use integer arithmetic and round down, as the contracts do.

21.3 Indexing

EventUse
LaunchCreatedDiscover launches, their pairs and window bounds
ContributedRunning totals; totalRaised is the total after the contribution
SettledMarket open time (settledAt), pool deposit, burn and start of the unlock
FailedSwitch the launch to refunds
Claimed, RefundedPer-user progress
CreatorFeeCredited, FeesWithdrawnFee accounting, including the base of the holders’ share (§13.5)
Pair: Sync, Swap, Mint, BurnPrice, volume and liquidity after settlement

Every factory state change can be rebuilt from these logs alone. Treat data as final only after finality, two epochs or about 12.8 minutes: until then, a reorg can move a contribution sent near the close into a block after it, where it reverts.

21.4 Transaction recipes

  • Contribute. contribute{value: x}(token). No approval is needed. Send it well before the end: a transaction included at or after start + WINDOW reverts.
  • Settle and trade. A contract can call settle(token) and swap on the pair in the same transaction. Searchers will; frontends show a settle button on closed launches.
  • Claim and sell. claim(token), then a swap through the Uniswap v2 router with amountOutMin derived from getReserves and a slippage tolerance.
  • Signature approvals. The token supports EIP-2612, so an approval can be a signature that a relayer, a smart account or a permit-aware router submits together with the swap.
  • Gasless claims. Anyone can call claimFor(token, user) and pay its gas; the tokens still go to user.
  • Batching. claimMany covers several launches. Smart accounts can bundle contributions to several launches in one operation.

21.5 Price oracles

The pair accumulates price0CumulativeLast and price1CumulativeLast from the settlement block. A time-weighted average over a period is the difference of two observations divided by the time elapsed. Moving that average costs the price impact of the pool’s depth, which EL and TL give from the first block.

21.6 Bots

Bots are first-class users. Everything they need is public and deterministic: token addresses come from predictToken, window bounds from LaunchCreated, the clearing price is raised / OPENING_SUPPLY at every moment, and settlement is permissionless. What they cannot buy is a better price in the window.

22. Deployment and verification

22.1 Addresses

ContractAddressDate
BlindfairFactoryCADATE
Project tokenCADATE
BlindfairTokenCreated by the factory at each launchAt each launch

An address is valid only when published on the official X account, @Blindfair.

22.2 Verifying the factory

  1. The source is verified on Etherscan, with its compiler version, optimizer settings and EVM version.
  2. The constructor arguments are the canonical WETH9 contract, the canonical Uniswap v2 factory and the protocol fee recipient.
  3. There is no proxy: the EIP-1967 implementation and admin slots are empty, and the bytecode has no DELEGATECALL to a mutable address and no SELFDESTRUCT.
  4. There is no owner(). The only caller restriction is on withdrawProtocolFees, which pays the fixed recipient.
  5. TOKEN_INIT_CODE_HASH equals the keccak256 of the verified BlindfairToken creation code, so every predicted address is the real one.

The checks for an individual launch are in §15.3.

22.3 Reproducing the build

Recompiling the verified source with the published compiler version and settings reproduces the deployed bytecode. Etherscan reports an exact match when the metadata matches as well, and anyone can repeat the comparison on their own machine.

23. Conclusion

Token launches fail the public for structural reasons: order is for sale, privilege is built in, wallets are exposed, early holders can exit at once, and contracts depend on the goodwill of their owners. Blindfair changes the structure rather than policing the actors. A single pooled window at a uniform price, no allocation outside it, liquidity that cannot leave, an unlock that starts with the market, a floor under the price, and no key that can change any of it. The privacy layer extends the same logic to visibility, within a framework designed to keep it from being abused.

Every launch has a list. On Blindfair, the list is empty.

Appendix A. Parameter summary

ParameterValueRationale
Total supply1,000,000,000§7.1
Opening supply500,000,000§7.2
Liquidity reserve500,000,000§7.2
Window10 minutes (600 seconds)§7.3
Unlock24 hours, linear, from settlement§7.4
Minimum raise1 ETH§7.5
Launch fee1%: half creator, half protocol (half of it to project token holders)§7.6
AMMUniswap v2, pair created at launch, LP to burn address§6.3, §7.7
Permanent floor24.75% of the window price§7.2, Corollary 5.1
Name and symbol limits32 and 10 bytes§6.3
Per-address capNone§7.8
Withdrawals during windowNone§7.9
ChainEthereum mainnet§7.10
Note denominations (phase 3)0.1, 1, 10 ETH§10.4
Merkle tree depth (phase 3)Grows with the number of notes, at most 20§10.5

Appendix B. Price impact and floor derivation

A constant-product pool holds T tokens and E ETH with invariant k = E · T. Its price is P = E / T.

Selling x tokens without fee gives new reserves T′ = T + x and E′ = k / T′ = E · T / (T + x). The new price is:

P′=E′T′=E⋅T(T+x)2P′P=(TT+x)2P' = \frac{E'}{T'} = \frac{E \cdot T}{(T + x)^2} \qquad\qquad \frac{P'}{P} = \left( \frac{T}{T + x} \right)^{2}

The relative price drop is 1 − (T / (T + x))². With Uniswap’s 0.3% fee, only 99.7% of x enters the invariant, so the true drop is slightly smaller. The bound is therefore conservative.

With T = TL = 495,000,000 and x = U(τ):

Time after settlementTokens sold xT / (T + x)Price ratioDrop
1 minute347,2220.999300.998600.14%
10 minutes3,472,2220.993030.986121.39%
1 hour20,833,3330.959610.920867.91%
6 hours125,000,0000.798390.6374236.26%
12 hours250,000,0000.664430.4414755.85%
24 hours and after500,000,0000.497490.2474975.25%

The last row is the permanent floor F of Corollary 5.1. Proposition 5 shows that these single-sale figures bound the price under any sequence of trades: the locked liquidity L0 = √(EL · TL) never shrinks, the locked position cannot hold more than TL + U(τ) tokens, and a position with liquidity L that holds T tokens implies the price (L / T)².

Symmetrically, buying with y ETH raises the price by a factor of ((E + y) / E)² before fees. In a launch that raised 20 ETH, a 1 ETH purchase right after settlement raises the price by about 10.4%: (20.8 / 19.8)² ≈ 1.104. With the fee, the factor is (1 + z)(1 + 0.997 z) with z = y /E, which reaches 2 at z ≈ 0.415: that is the last row of the table in §13.2. A purchase of y ETH receives T · 0.997 y / (E + 0.997 y) tokens; in the same launch, 1 ETH buys about 23.73 million tokens and 5 ETH about 99.56 million (§9.4).

General form. Since TL = (1 − f) · So by formula (5), the bounds of Section 8 depend neither on the raise nor on the split, only on the fee and on the share of the unlock elapsed:

P(τ)p  ≥  (1−f1−f+min⁡(τ,V)/V)2Fp=(1−f2−f)2=(0.991.99)2≈0.2475\frac{P(\tau)}{p} \;\ge\; \left( \frac{1 - f}{1 - f + \min(\tau, V)/V} \right)^{2} \qquad\qquad \frac{F}{p} = \left( \frac{1 - f}{2 - f} \right)^{2} = \left( \frac{0.99}{1.99} \right)^{2} \approx 0.2475

Why the split is 50/50. Price continuity fixes the pool at TL = (1 − f) · So tokens, and the liquidity reserve must cover it: S − So ≥ (1 − f) · So, so So ≤ S / (2 − f) ≈ 502,512,562 tokens. The remainder, S − (2 − f) · So, is burned at settlement: 5,000,000 tokens with So = 500,000,000. A smaller opening share would change neither the bounds above nor the depth of the pool relative to participants’ holdings; it would only burn more of the nominal supply.

Appendix C. Glossary

TermMeaning
AllocationTokens owed to a window participant: So · ci / C
Anonymity setThe notes among which a private note is indistinguishable
Association setA published set of approved deposits; a proof shows membership without revealing which member
ASPAssociation set provider
BindPhase 3 operation that credits a private note to a fresh address
BundleSeveral purchases by one actor, often included with a deployment in the same block
ClaimTransfer of unlocked tokens to the holder
CommitmentH(s, ν), the public fingerprint of a private note
CREATE2Opcode that deploys a contract at an address computable in advance
FactoryThe Blindfair contract that creates and runs every launch
FDVFully diluted value: price × supply excluding burned tokens
Floor (F)The lowest price the pool can ever reach: 24.75% of the window price
Locked liquidity (L0)The pool’s initial liquidity, √(EL · TL), held by the burn address forever
LP tokensReceipts for pool liquidity; burned on Blindfair
MEVValue extracted by including, excluding or reordering transactions
NoteA fixed-denomination private contribution
NullifierSecret whose hash is revealed when a note is used, preventing double use without revealing the note
Opening windowThe 10 minutes after creation during which anyone can contribute
Public exitPhase 3 operation that credits a note to its depositor, without privacy
RelayerA party that submits transactions on behalf of a fresh address
SaltCREATE2 input; on Blindfair, derived from the creator and their launch count
SandwichMEV attack placing trades before and after a victim’s trade
SettlementThe transaction that clears the window, seeds the pool, burns the LP and starts the unlock
SniperActor who buys the instant a token becomes purchasable
SybilOne actor operating many addresses
Uniform priceThe single price paid by every window participant
UnlockLinear 24-hour release of opening allocations, starting at settlement

Appendix D. Frequently asked questions

Can the creator or the developer take the ETH or the liquidity?

No. The contracts have no owner and no admin function. At settlement, 99% of the raise goes into the pool and the liquidity tokens are burned; the remaining 1% is the fee (§6.6, §11.6).

Can the creator keep tokens for themselves?

Only by contributing in the window like everyone else, at the same price and under the same unlock. There is no creator allocation (§6.3, Proposition 11).

Does contributing early give a better price?

No. Everyone in the window pays the same price, fixed at the close (Proposition 1).

How do I know what price I will pay?

Not until the close. The price at the moment you contribute is your best case; later contributions can only raise it (§9.3).

What if a window raises less than 1 ETH?

The launch fails, all its tokens are burned and every contributor can withdraw their full contribution, with no fee (§6.10).

When can I sell?

Your tokens unlock linearly over 24 hours from the moment the market opens. You can claim and sell the unlocked part at any time (§6.8, §6.9).

Why can’t I sell everything at once?

So that nobody can dump on the first buyers. One minute after the market opens, at most 0.07% of every allocation is sellable (Proposition 5).

What does the price floor mean?

The pool price, in ETH, can never fall below 24.75% of the window price, because the locked liquidity can never leave and the supply is fixed. It is not a guarantee of value: it is denominated in ETH and assumes the contracts work as specified (Corollary 5.1).

Who calls settle, and what if nobody does?

Anyone can, without reward; participants, searchers and the application all have reasons to. Until settlement the market is closed and nothing unlocks, so a delay changes the timing, not the fairness (§6.6, §6.8).

Why does the factory appear as a large holder?

It holds unclaimed allocations until their owners claim them (§15.4).

Are there fees on trading?

No transfer tax. Trades pay Uniswap’s usual 0.3% swap fee, of which 0.05% currently goes to the Uniswap protocol (§13.3).

Can bots still make money?

Not in the window. After settlement, the pool is an ordinary Uniswap market and bots trade there as anywhere else (§9.5).

Is my participation private?

Not in the current version: contributions are public. Phase 3 adds private contributions (§10).

Is there a project token?

Yes. It launches alongside the launchpad, on Uniswap v4, with 100% of its supply in the pool and its liquidity burned. Holders receive 0.25% of every raise in ETH (§13.5).

Why isn’t the project token launched on Blindfair?

Because the factory has no special path for its developer. Launching it there would make the developer the creator of that launch, with its creator fee and its timing (§13.5).

Appendix E. References

  1. V. Buterin. EIP-1014: Skinny CREATE2. Ethereum Improvement Proposals, 2018.
  2. H. Adams, N. Zinsmeister, D. Robinson. Uniswap v2 Core. 2020.
  3. V. Buterin, J. Illum, M. Nadler, F. Schär, A. Soleimani. Blockchain Privacy and Regulatory Compliance: Towards a Practical Equilibrium. 2023.
  4. P. Daian, S. Goldfeder, T. Kell, Y. Li, X. Zhao, I. Bentov, L. Breidenbach, A. Juels. Flash Boys 2.0: Frontrunning, Transaction Reordering, and Consensus Instability in Decentralized Exchanges. IEEE Symposium on Security and Privacy, 2020.
  5. L. Grassi, D. Khovratovich, C. Rechberger, A. Roy, M. Schofnegger. Poseidon: A New Hash Function for Zero-Knowledge Proof Systems. USENIX Security Symposium, 2021.
  6. EIP-2612: Permit Extension for EIP-20 Signed Approvals. Ethereum Improvement Proposals.
  7. H. Adams, K. Ng, D. Walsh. UNIfication. Uniswap Labs blog, 10 November 2025.
  8. A. Gilbert. Uniswap DAO to activate ‘fee switch,’ burn almost $600m UNI token. DL News, 26 December 2025.
  9. Ethereum Foundation. Glamsterdam Repricing Impact for Smart Contract Developers. Ethereum Foundation Blog, 24 August 2026.
  10. E. Sheridan. Glamsterdam in plain English: how Ethereum plans to cut out the middlemen in block building. investingLive, 7 October 2026.
  11. Privacy & Scaling Explorations. LeanIMT, Lean Incremental Merkle Tree (@zk-kit/lean-imt.sol). zk-kit.

Disclaimer

This paper describes the Blindfair contracts deployed on Ethereum mainnet. Their parameters are fixed in code and cannot change. Nothing in this paper is financial, legal, tax or investment advice, or an offer to sell or a solicitation to buy any asset. Smart contracts can contain bugs, and funds can be lost without any possibility of recovery, because by design no one holds administrative keys. The price floor described in Section 8 is a mathematical property of the contracts as specified, denominated in ETH; it is not a guarantee of value. Blindfair does not review, endorse or vouch for any token launched through it. Token prices can fall sharply. Privacy features depend on user behavior and may be restricted in some jurisdictions. Blindfair is not available to sanctioned persons or in sanctioned jurisdictions. Use only what you can afford to lose.