XLINK
XL DocsLaunch App

XL.money

Contents

The 60-second version

Someone launches a coin for your X handle. Every trade drops a fee into your on-chain pot — automatically, whether or not you ever engage. To pull it to your own wallet, sign in with X. Or, for US handles, anyone can have it delivered straight to your X Money — you don't have to sign in or do anything. Coin holders earn a share too.

The chain: launch a coin -> trades happen -> your pot fills up -> either sign in with X to claim it to your own wallet, or (US handles) have it delivered to your X Money on request, no sign-in needed.

Nothing to set up in advance. Your pot exists the moment the coin launches.


Launch your first coin

You do not need a wallet or any crypto to have a coin launched for your handle. Anyone can launch one. The pot belongs to you the moment you sign in with X.

  1. 1
    Step 1: Enter a handle

    Type any X handle. That handle's pot will receive the creator fees from every trade.

    handle (required) name (required) ticker (required) image (required)

  2. 2
    Step 2: Fill in the details

    Name the coin, pick a short ticker, upload a logo. X and Telegram links are optional but show on the coin's page. Set a developer buy amount if you want to buy at launch price before anyone else. Holder reflections are on by default; you can switch them off for your coin, and that choice is permanent for that coin.

    X link (optional) Telegram (optional) dev buy (optional) holder reflections (on by default)

  3. 3
    Step 3: Confirm and launch

    Connect your wallet, sign the transaction. The coin goes live instantly on the Pons V2 bonding curve.


Fees without the fine print

Every trade on your coin pays a creator fee. Here is where each slice goes.

2% total floor tax1.0% to the handle pot 0.5% to coin holders (reflections, on by default) 0.3% to Pons 0.2% to XL treasury

Reflections are on by default for every new coin. The launcher can switch them off for their coin at launch, and that choice is pinned forever for that coin: with reflections off, the holders' 0.5% goes to the handle pot instead, so the pot receives 1.5% and holders receive nothing. Above the 2% floor, every extra 1% of tax splits half to holders and half to the pot when reflections are on, and all to the pot when they are off. XL treasury and Pons stay fixed at 0.2% and 0.3% whatever the tax.

These splits are set in the deployed factory contract and are readable by anyone. The contract address is in the section below.

One additional fee: X Money delivery, which anyone can request for a pot, takes a 5% delivery fee out of that pot. Claiming to your own wallet has no delivery fee at all.


Your pot

Every trade on a coin launched for your handle sends the creator share to your on-chain pot. The pot is a smart contract deployed specifically for your X user ID, not a server wallet. XL.money cannot redirect the balance to an address of its choosing. One exception, on a public schedule: a pot that nobody has claimed and that has seen no trading fees and no reflection claims for 14 days can be marked abandoned (an on-chain notice), and after a further 14-day notice window swept to the XL treasury. Any activity in between cancels it.

The balance shown on xl.money/pots is sometimes marked DERIVED, which means it was calculated from on-chain events rather than a direct contract read. The contract is always the source of truth.

You do not have to do anything for the pot to fill up. It accumulates automatically as people trade the coin.


Claiming your cut

To claim, sign in with X. XL.money verifies you own that handle using X OAuth. Then give the wallet address you want paid. The whole pot is sent there in one go, and XL.money pays the gas. Each claim is one shot: next time there is something in the pot, sign in again. Post the share on X when the claim card asks; the claim is released once the post is verified.

We will never ask for your seed phrase or private key. The sign-in flow is X OAuth only. Signing a message in your wallet proves you control it. Nothing more.

Claim to your own EVM wallet: free, no delivery fee, no gas, arrives right after you sign in.

X Money delivery: 5% delivery fee, US accounts only (X Money is a US product), live today. The last step, the X Money send itself, is done by a person at XL.money, so allow a little time.


Reflections: earning while you hold

Reflections are live. On every coin launched with reflections on (the default), holders share 0.5% of every trade at the 2% floor tax, and more if the launcher set a higher tax.

Holders earn a share of every trade, paid in USDG from a per-coin pool on chain. Each epoch, XL.money's keeper snapshots who held what, weights it by the multiplier below, publishes the result, and sends each qualifying wallet its share directly, paying the gas. If a wallet cannot be paid directly (a contract wallet, or a transfer it rejects), its share waits in the pool and can be claimed from it at any time; nothing expires.

The pool contract is ReflectionDistributor in the address table below. Every push and every claim is an on-chain event you can check.


The multiplier

Live. Your reflections are weighted by how you hold: a multiplier of up to 2x on your time-weighted balance.

The multiplier rewards holding: consecutive epochs held build a streak, burns count in your favor, and selling during an epoch counts against you for a while. It is computed by XL.money's keeper from on-chain transfers, capped at 2x, and published with each epoch so anyone can check the weights. It applies to coin holders' reflections, not to the handle's pot, which always receives its full share.


Graduation day

When a coin's bonding curve fills to the Pons V2 threshold, it graduates to the open DEX on Robinhood Chain. After graduation the coin trades freely on the DEX. Your pot keeps receiving creator fees from any continued volume.

Graduated coins show a chip on their page and in the leaderboard.


What's real and verifiable

Everything below is on-chain. You do not have to trust XL.money's word on any of it.

WhatAddress
Factory contract (v2.1, live)0x16D36c555Eb5AB96a1159Cbc5B6d9582d3D7eb36
Pot implementation (v2.1)0x810d0a4A0B1d0c787819896C7f9aaB06C36cEd3d
Reflections pool (ReflectionDistributor)0xD5587eaB8C3e44bD8772139B00123f0b65632016
$XL tokenNot yet launched -- announced at launch
Explorerhoodscan.co

The deployed bytecode of every contract above was checked byte for byte against the published source build; the method and results are in the technical reference. The source is in the open repository, and every value the docs quote can be re-read from the chain without any signup.

Three security properties that are enforced by code, not promises:

  1. XL.money admin keys cannot pay a pot's balance to an address of their choosing. A claim goes only to the wallet named in the oracle-signed attestation from your X sign in; a delivery goes only to the delivery wallet recorded when it was requested; an abandoned-pot sweep can pay only the XL treasury, and only after 28 days of public silence.
  2. The identity signer is the one key that authorizes a claim. It lives only inside a hardened, caller-gated Cloudflare Worker, and the guardian can revoke it instantly, which voids every outstanding signature.
  3. Reflections pools are isolated per coin and solvency-checked on chain; the keeper cannot pay one coin's holders from another coin's pool.

Each is covered by fork tests that fail automatically if it stops being true.


Quick answers

Who can launch a coin for my handle? Anyone. You do not have to launch it yourself. Once the coin exists, only you can claim the pot by signing in with X.

What chain is XL.money on? Robinhood Chain (chain id 4663). Coins trade against USDG on the Pons V2 bonding curve.

What if I did not authorize a coin for my handle? The pot is yours the moment you sign in with X. No one else can claim it. You can claim the funds the moment you verify ownership.

What is the delivery fee? 5% of the pot, paid only if you use the community delivery path to X Money. Claiming to your own wallet has no delivery fee.

Does XL.money hold my funds? Your pot is a smart contract. XL.money cannot move your funds against your will. The on-chain proof is linked in the section above.

Is X Money delivery live? Yes, for US accounts, since 2026-09-13. The on-chain steps and the bridge run automatically; the final X Money send is made by a person at XL.money, and you get a real X Money notification with a note.

What is the $XL token? The real $XL has not launched yet; it will be announced on @X_Link_Money at launch. The coin launched under XL.money's own test handle during the build was an end-to-end test, not $XL.

Can non-US handles use XL.money? Yes. Any X handle can launch a coin and claim the pot to an EVM wallet. The X Money delivery option is US-only because X Money is a US product.


Words we use

potThe on-chain smart contract that holds a handle's earned creator fees.
reflectionsFees distributed to coin holders on every trade, proportional to holdings.
graduationWhen a coin leaves the bonding curve and starts trading on the open DEX.
dev buyA purchase the coin launcher makes at the moment of launch, before anyone else can trade.
handleAn X account username, for example @X_Link_Money.
DERIVEDA balance figure calculated from on-chain events rather than a live contract read. The contract read is always the source of truth.
multiplierThe up-to-2x weighting XL.money applies to a holder's reflections based on how they hold.
// xl.money docs :: machine build :: for agents, not followers // raw: /docs/raw | ?download=1 for file
Contents

XLINK technical reference

This is the canonical technical description of XLINK: what it is, exactly how a dollar moves from a trade on a bonding curve to a notification in someone's X Money account, what is enforced on chain versus what depends on a human, and how to check every claim below yourself. It is written for a person auditing the product and for an AI agent reading xl.money and trying to describe it accurately. Every fact below names the file it came from. Where a value could change on chain (a fee, a threshold, an address), the file and the exact getter to re-read it live are both given, because a document goes stale and a chain read does not.

Status as of this writing (2026-09-13): the v2.1 contracts are deployed on Robinhood Chain (chain id 4663) and bytecode-verified against the compiled artifacts, the identity and ledger services, the signer and the keeper run against them, and every automated leg is switched on: one-shot claims are paid by the keeper, community delivery and the fiat rail execute automatically, and holder reflections are distributed each epoch with the multiplier. The launch, fee-split and claim legs have been exercised with real value on the live contracts: a coin launched through the public site for a third-party handle, real trades split fees into the pot, the holders' pool and the treasury exactly as the contracts compute, and the handle's owner claimed the pot with a real X sign in. Community delivery to X Money and the fiat rail are switched on but have not yet been exercised on v2.1 (the rail itself was proven standalone; no v2.1 on-chain delivery has run). Everything under "Known limitations and open items" below is real and current, not boilerplate.

The handful of values a reader reaches for first, gathered in one place. Each row's source column names the file or config constant that is the actual source of truth; if this table and that source ever disagree, the source wins, not this table.

WhatValueSource
X account@X_Link_MoneyNEXT_PUBLIC_BRAND_HANDLE (app/src/lib/env.ts's brandHandle), surfaced to the docs page via app/src/lib/site-links.ts's socialLinks. This page is statically generated, so this row reflects whatever value was configured at the last production build, not necessarily this instant; the account can be renamed with a single env var edit, followed by a rebuild and deploy, no other edit required.
$XL tokenNot yet launched -- announced at launchThe real, official $XL has not launched. app/src/lib/site-links.ts's xlTokenAddress reads NEXT_PUBLIC_XL_TOKEN_ADDRESS, unset today; this row switches to the live address automatically the moment that env var is set and this page rebuilds. 0x62A0AbF3C22230adDA6A0283CF3DaFe5759C8bb6 is an E2E test coin under XLINK's own house handle xcoinpad, not $XL -- see "The retired v1 factory, and why it is retired" below.
HandleVaultFactoryV21 (v2.1, live)0x16D36c555Eb5AB96a1159Cbc5B6d9582d3D7eb36"Contracts and addresses on chain 4663" below; contracts/DEPLOYMENTS.md; the deploy broadcast
HandleVaultV21 implementation0x810d0a4A0B1d0c787819896C7f9aaB06C36cEd3dsame as above
ReflectionDistributor (holder reflections pool)0xD5587eaB8C3e44bD8772139B00123f0b65632016same as above; read reflectionDistributor on the factory
HandleVaultFactory (v2, previous; still consulted by v2.1 for squat prevention)0xcB1C296F4b964cC03Ba89D4414Cf7B9BA1da117b"The v2 factory (previous)" below; read v2Factory on the v2.1 factory

Explorer: hoodscan.co (NEXT_PUBLIC_EXPLORER_BASE, app/src/lib/env.ts's explorerBase). Every address above is also cited in full, with deploy transactions and block numbers, in "Contracts and addresses on chain 4663" below.

XLINK lets anyone launch a Pons V2 bonding-curve coin "for" an X handle. The coin's on chain creator fee recipient is not a person's wallet and not XLINK's wallet: it is a per-handle smart contract, HandleVaultV21 (a "pot"), plus, for a coin with holder reflections on, a per-coin FeeSplitter in front of it. Money leaves a pot in exactly three ways, all on chain: the handle's verified owner claims it in one shot (sign in with X, name a wallet, the whole available balance is paid there at no fee); anyone asks XLINK to deliver an unclaimed pot to that person's X Money account for a fee, in public; or, for a pot nobody has claimed and nobody has traded against for 14 days, XLINK's owner key may mark it abandoned and, after a further 14-day public notice window, sweep it to the platform treasury and nowhere else. No admin key has a function that pays a pot's balance to an address of the admin's choosing: a claim's destination is fixed by the oracle-signed attestation, a delivery's destination is the delivery wallet snapshotted at request time, and the sweep can only pay platformTreasury (contracts/src/v21/HandleVaultV21.sol:543,634,706; contracts/src/v21/AbandonmentManagerV21.sol:673). Those properties are proven by fork tests that exist specifically to fail if they stop being true: test_claim_fullBalancePayout_pendingPlatformShareReserved, test_ec14_guardianRevokeOracle_invalidatesAttestation and test_sweepAbandonedVault_onlyFactoryCanCallVaultSweep (contracts/test/v21/ClaimV21.t.sol, EmergencyControlsV21.t.sol, AbandonmentV21.t.sol).

The differentiator against a plain fee-split launchpad is the payout destination: fees are meant to land as an X Money peer to peer payment from XLINK's own X account, with a public note, so the handle owner gets a real X notification and can share it (internal decision record, not published: "the whole point of XLINK is that fees earned by a coin launched for an X handle end up in that person's X Money balance"). An on-chain-only release to a wallet is the honest fallback for someone who would rather self-custody than wait for or trust the X Money leg; it is not the product's headline path.

XLINK is the rebuild of an earlier, dishonest project by the same operator, xcoins.fund, whose "fees bridged straight into X Money" claim never happened for any coin except its own, and whose per-coin fee recipients were plain server-held wallets, not contracts . XLINK's whole design is a reaction to that: the per-handle vault is non-custodial in the sense that matters (no server-held key can move funds out of it against its owner's will; see "The trust model" below), and no present-tense claim that outruns what is actually live on chain and on the rail, checked below ( discipline was held while the legs were being built). That claim is narrower than "XLINK never touches a handle's money": once a vault's balance leaves it through executeDelivery, it lands first in deliveryWallet, an XLINK-controlled address, before continuing on to PayPal and then X Money (see "The delivery fee" and "The X Money receive flow, as verified" below); and a pot with no claim, no fee activity and no reflection claims for 14 days may be marked abandoned by the factory owner and, after a further 14-day public notice window, swept to the platform treasury (see "Abandoned pots" under "Known limitations and open items" below). Both are real, named custody hops on a stated schedule, not a hidden one: the guarantee is that nobody can redirect a vault's funds against its owner, not that the money never touches an address XLINK controls.

The end to end flow

Every hop, named, in order. Contract function names are exact; file paths are given for each hop so a reader can go straight to the source.

  1. A vault is created for an X handle. HandleVaultFactoryV21.createVault deploys a deterministic EIP-1167 minimal proxy clone of the shared HandleVaultV21 implementation, keyed by the handle's numeric X user id, never by the handle string (a handle string can be released and reused; the numeric id cannot). Before creating, the factory consults the previous v2 factory's vaultOfHandle and refuses (HandleTakenOnV2) if that handle already has a v2 vault, so no handle can be squatted across the two factories. There are two ways to call it: XLINK's own allowlisted keeper key can call the two-argument overload directly, and anyone else must present an oracle-signed LaunchTicket to the four-argument overload (contracts/src/v21/HandleVaultFactoryV21.sol:593,598,619).
  2. The coin launches through the vault. HandleVaultV21.launch calls Pons V2's PonsV2LaunchFactory.launchToken, forwarding exactly Pons's own live launchFee and nothing more, with one extra argument v2 did not have: reflectionsEnabled, on by default in the launch form and pinned forever at the vault's first launch. With reflections off the vault itself is the coin's creatorFeeRecipient; with reflections on the factory deploys a fresh per-coin FeeSplitter clone and sets that as the recipient, so the holders' share can be carved out before anything reaches the vault. Same two-path shape as vault creation: an allowlisted launcher calls the plain overload, everyone else needs an oracle-signed LaunchTicket naming their own address as the launcher for that exact vault (contracts/src/v21/HandleVaultV21.sol:287,297; HandleVaultFactoryV21.sol:982; app/src/lib/launch-tickets.ts:124). Every coin launched under the current factory must pair against USDG; launch reverts PairNotAllowed for a native ETH pair.
  3. Trading accrues a creator tax and Pons's own base fee inside Pons's own escrow, not inside the vault yet. This is Pons V2's mechanism, external to XLINK's contracts; XLINK reads it via PonsV2FeeEscrow.balanceOf / balanceOfToken. For a reflections-on coin the keeper first calls FeeSplitter.collect(curve), which sweeps the curve, pays the community share straight into the ReflectionDistributor pool for that coin, and re-credits the remainder into Pons's escrow under the vault's address, so the vault's own claimFees cannot tell it apart from a direct Pons payment (contracts/src/v21/FeeSplitter.sol:257, .
  4. claimFees pulls the accrued amount out of Pons's escrow into the vault and, in the same transaction, computes and pays the platform's fixed share of that delta to platformTreasury before leaving the remainder as the handle's available balance. There is no keeper tip in v2.1; the keeper pays its own gas (contracts/src/v21/HandleVaultV21.sol:447). See "The fee model" below for the exact split.
  5. The handle's owner claims by X sign in. runs the X OAuth 2.0 PKCE flow, resolves the caller's numeric xUserId, takes the wallet the owner wants paid, and issues an EIP-712 Attestation {handleHash, xUserId, to, deadline, nonce, oracleEpoch} signed by the identity oracle key inside the signer Worker. The to field is bound to the signed-in X proof, so a leaked attestation cannot be redirected, and the deadline may not be more than one hour out (MAX_ATTESTATION_TTL, contracts/src/v21/HandleVaultV21.sol:130; .
  6. claim pays the whole pot in one shot, at no fee. Anyone may submit the attested claim (XLINK's keeper does, from a gas-only key, so the owner pays no gas); the vault checks the handle, user id, nonce, oracle epoch and signature, then pays 100% of the available pair-token balance to Attestation.to and increments the per-vault claimNonce. There is no persistent owner, no contest window, no re-bind and no partial release: the next claim is a fresh sign in and a fresh attestation (contracts/src/v21/HandleVaultV21.sol:543;, CLAIMS_PAYOUT_ENABLED).
  7. Or, instead of a claim, anyone can ask XLINK to deliver a pot's balance to X Money: permissionless requestDelivery then executeDelivery. This is the "community delivery" path, and since v2.1 it is also how a handle's owner gets X Money: there is no fee-free owner route to X Money any more, because there is no owner-only release. The request has no minimum balance and no pre-empt window today: deliveryDelay is deployed at 0 (the contract's MIN_DELIVERY_DELAY), so a request is executable immediately; the factory owner can raise it up to 7 days at any time with no timelock, so read deliveryDelay live rather than trusting this number (contracts/src/v21/HandleVaultV21.sol:593; HandleVaultFactoryV21.sol:176,177,825).
  8. executeDelivery pays a delivery fee to platformTreasury and the rest to deliveryWallet. Only factory.deliveryOperator may call it; that role is XLINK's gas-only keeper key, distinct from the delivery wallet, the deployer and the oracle. The fee and destination used are the ones snapshotted when the request was made, never a live factory read at execution time, so a later fee or wallet change can never re-price a request already in flight (contracts/src/v21/HandleVaultV21.sol:634; read deliveryOperator live).
  9. USDG in the delivery wallet is bridged one hop to PYUSD at PayPal's own receive address on Ethereum, entirely off chain 4663, via a single LI.FI transaction (; verified live 2026-09-11, 10 USDG in one chain-4663 transaction landed as 9.8692 PYUSD at PayPal's deposit address about 4 seconds later, .
  10. PayPal credits the PYUSD, and a human sells it for US dollars inside PayPal. This is a manual tap: PayPal has no API to auto-convert received crypto and no auto-sell setting for it .
  11. PayPal's own daily automatic transfer, or a manual PayPal instant transfer (1.5%, minutes), moves the US dollar balance into X Money, which is a linked bank inside PayPal's own UI, exactly like linking any other bank (; PayPal to X Money instant transfer measured live at 1.5% with a $0.50 minimum).
  12. A human sends the X Money peer to peer payment to the handle owner, from XLINK's own X account, with a note. This is the one remaining manual step in the money's actual path and is intentionally never scripted; see "What is not automated" below.
  13. A public proof is posted. The keeper only posts the "delivered" announcement after it independently observes, via the the delivery record, that the operator actually marked the payment sent; it never announces a payment before it went out ( before").
  14. The public activity feed shows the whole lifecycle. GET /activity merges on chain Launched / FeesClaimed / HandleClaimed / DeliveryRequested / Delivered events (and the previous factories' Bound / Released / AutoReleased, under the same kinds) with the public-safe fields of the same the delivery record rows, so a pending request, a sent payment, and a claimed or paid-out state are all visible without trusting a dashboard ().

The whole chain, compressed to one line, matching the operator's own description : Pons trade to Pons escrow (via the coin's FeeSplitter when reflections are on) to claimFees into the vault to owner sign in and one-shot claim to a wallet, or community requestDelivery/executeDelivery to USDG bridged to PYUSD at PayPal to a manual sell to US dollars to a transfer into X Money to a manual peer to peer send with a public note.

The fee model, exactly as configured

Every number here is read from the actual deployed HandleVaultFactoryV21 constructor arguments (the deploy broadcast, summarized in contracts/DEPLOYMENTS.md and contracts/deployments/v21-2026-09-13.json) and cross-checked against .1: community reflections" sections and contracts/src/v21/HandleVaultV21.sol, HandleVaultFactoryV21.sol and ReflectionFeeMath.sol directly. Nothing here is a plan; this is what is live on chain today.

Two fees exist, and they apply at two different moments. The creator tax and Pons's own base fee are set once, at a coin's first launch, and apply every time claimFees pulls money out of Pons's escrow into the vault. The delivery fee applies once, only if and when the community delivers an unclaimed vault's balance to X Money through the permissionless requestDelivery/executeDelivery path, on top of whatever claimFees already took. The owner's one-shot claim to their own wallet pays neither fee beyond what already landed in the vault; it always moves 100% of the vault's available balance, with no fee (contracts/src/v21/HandleVaultV21.sol:543, no fee logic in that function's body). A third slice, the holders' reflections share, is carved out before claimFees for coins launched with reflections on; see "Reflections" below.

The creator tax floor and its 80/20 split

  • HandleVaultFactory.floorTaxBps is deployed at 100 (1.00%). This is both the lowest creatorTaxBps a coin may launch at, and the base XLINK's own claim-time share is computed against (.
  • HandleVaultFactory.platformShareOfFloorBps is deployed at 2,000 (20% of that 1% floor), capped on chain at MAX_PLATFORM_SHARE_OF_FLOOR_BPS = 2_000 (contracts/src/v21/HandleVaultFactoryV21.sol:173) after round 5 of the external audit lowered it from an original 5,000 (the audit record. So of the 1% floor tax itself: 0.8% of volume to the handle, 0.2% of volume to XLINK (app/design/PILL-FACTS.md line 8: "tax floor 1%: 0.8% handle + 0.2% XLINK").
  • Separately, Pons's own base curve fee for the current launch config is 1% of volume, which Pons's own fixed policy (read live at launch time, not configured by XLINK) splits 0.7% of volume to the coin's creator fee recipient (the vault) and 0.3% of volume kept by Pons's protocol (; app/src/lib/launch.ts:34, PONS_BASE_SHARE_BPS = 30).
  • Added together, the minimum total tax on every trade at the floor is 2.00% of volume: 1% XLINK floor plus 1% Pons base fee. Of that 2%, the handle keeps 1.5% (0.8% plus 0.7%), XLINK keeps 0.2%, and Pons's own protocol keeps 0.3%. This is the "2% creator tax floor" figure used in operator notes and product copy ; the 80/20 split specifically names XLINK's own 1% component of that 2%, never the whole 2%.
  • Above the floor, a launcher may set creatorTaxBps up to Pons's own maxCreatorTaxBps, which was read live as 1,000 (10%) (.ts:32, MAX_CREATOR_TAX_BPS = 1000`). Every basis point above the 1% floor goes 100% to the handle; XLINK's own cut of volume is pinned at 0.2% regardless of how high the launcher sets the tax ( DENOMINATOR"). Two different, correctly distinct ways to express the handle's resulting share exist in this codebase and should not be confused:
  • Share of the money claimFees actually delivers to the vault (excludes Pons's own protocol cut, which never reaches the vault at all): at the 1% floor this is 20 / 170 is about 11.76% to XLINK and 150 / 170 is about 88.24% to the handle; at the 10% cap it is 20 / 1070 is about 1.87% to XLINK and 1050 / 1070 is about 98.13% to the handle. This is HandleVault.platformShareOf's exact, on-chain, currently-pinned-per-vault formula (. Those two ratios are for a reflections-off coin. With reflections on, the vault's pinned denominator is reduced by the community share (platformShareDenominatorBps = T + 70 − C, contracts/src/v21/ReflectionFeeMath.sol:66-97), because the holders' C never reaches the vault at all: at the 1% floor with reflections on, what reaches the vault is 120 bps of volume, of which 20 / 120 is about 16.67% to XLINK and 100 / 120 is about 83.33% to the handle; XLINK's 0.2% of volume is unchanged either way.
  • Share of the total volume-based tax the trade pays, including Pons's own protocol cut (a marketing simplification, computed by app/src/lib/launch.ts's creatorTaxSplit, used on /launch and /h/[handle]): at the 10% cap, vaultBps is 1000 minus 20 plus 70 equals 1050, against a total of 1050 plus 20 plus 30 equals 1100, a ceiling of 95% at the current 10% tax cap (app/src/lib/launch.ts:53). A home-page "Up to 95%" marketing pill built on this figure was removed in the 2026-09-12 UI round 6 pass in favor of a first-mover headline claim instead (app/src/components/xl/orbit-center.tsx's own comment: "Never revert this to 'Up to 95%' without a fresh operator call"). Today the figure only appears, computed live via creatorTaxSplit, in the three-line fee breakdown on /launch (app/src/app/launch/LaunchForm.tsx:1058 to 1059) when a launcher actually sets creatorTaxBps to the cap; it answers "of everything this trade pays in tax, how much reaches the handle," not "of what the vault claims, how much is XLINK's." Note that creatorTaxSplit does not subtract the holders' reflections share, so on a reflections-on coin (the default) the "to the pot" figure it prints is the pot plus the holders' pool together, not the pot alone.
  • The fee split is pinned per vault at first launch and can never be re-priced by a later factory-level change. TaxPinned / pinnedCreatorTaxBps on the vault; a relaunch at a different tax reverts instead of silently changing the split on already-accrued fees (the audit record.
  • Both floorTaxBps and platformShareOfFloorBps are owner-settable but only affect vaults that have not launched yet, and both sit behind a 7-day timelock as defense-in-depth (contracts/src/v21/HandleVaultFactoryV21.sol:758,778; FLOOR_TAX_BPS_TIMELOCK and PLATFORM_SHARE_OF_FLOOR_BPS_TIMELOCK at lines 178 to 179, both 7 days; a floor below 100 bps is refused outright at proposal time, FloorTaxBpsBelowMinimum, line 139).

Reflections: the holders' share, live

  • Reflections are a per-launch toggle, on by default, pinned forever at a vault's first launch (pinnedReflectionsEnabled, ReflectionsTogglePinned, contracts/src/v21/HandleVaultV21.sol:154; default true in app/src/lib/launch-tickets.ts:124; the toggle is in step 2 of /launch).
  • The split, in bps of volume, from ReflectionFeeMath.computeSplit (contracts/src/v21/ReflectionFeeMath.sol:66-97): community C = 50 + (T − 100) / 2 when on, 0 when off, where T is the creator tax; XLINK stays floorTaxBps × platformShareOfFloorBps / 10000 = 20; the handle gets the rest. At the 1% creator-tax floor (T = 100; 2% total trade tax) with reflections on: 0.5% of volume to holders, 1.0% to the handle, 0.2% to XLINK, 0.3% to Pons; with reflections off the holders' 0.5% folds back into the handle's 1.5%. Every extra 1% of tax above the floor splits half to holders and half to the handle when on, and all to the handle when off (contracts/REFLECTIONS-DESIGN-MEMO.md section 5). A reflections-on coin must set T on the 50-bps grid (CreatorTaxNotOnGrid).
  • Mechanism. The factory deploys one FeeSplitter clone per reflections-on coin (HandleVaultFactoryV21.deploySplitter, implementation 0x6b47541a9771e518366dc06a3A12332AF02Bb683) and sets it as the coin's Pons creatorFeeRecipient. Permissionless collect(curve) sweeps the curve, deposits C into the shared ReflectionDistributor (0xD5587eaB8C3e44bD8772139B00123f0b65632016, pool keyed by the splitter's address) and re-credits the remainder into Pons's escrow under the vault, so the vault's unmodified claimFees then applies its own pinned XLINK numerator to what arrives (contracts/src/v21/FeeSplitter.sol:14-59,257; ReflectionDistributor.sol:165).
  • Distribution is push-primary, pull-fallback, with a multiplier of up to 2x. Each epoch the keeper snapshots holders from Transfer logs (curve, pool, locker, vault, splitter and dead addresses excluded), weights each holder's time-weighted balance by a multiplier min(S × U × B × L × D, cap) built from hold streaks, sell penalties, burns and locks, commits a cumulative Merkle root (commitEpoch) and pays qualifying EOA holders directly (pushBatch), XLINK paying the gas; anyone a push skips (a contract holder, a rejecting recipient, a sub-dust entitlement) stays pull-claimable against the same root via claim for as long as the pool exists. Cumulative totals make push and claim replay-idempotent (contracts/src/v21/ReflectionDistributor.sol:14-49,193,227,310; section 4;, EPOCH_ENABLED, EPOCH_PUBLISH_ENABLED, both on in production since 2026-09-13).
  • Trust statement, verbatim from the contract: the epoch keeper (factory.epochKeeper, read it live) is trusted with a pool's funds up to what it has allocated; the contract enforces pool isolation and solvency, not allocation honesty; the published root makes a dishonest allocation publicly provable but not preventable. The guardian can pause the distributor and any splitter instantly (ReflectionDistributor.sol:384).
  • Proven live on 2026-09-13: on the first reflections-on coin launched through the public site (creator tax 2%, so C = 100), one collect-and-claim split 4.658 USDG into 2.588 to the pot, 1.725 to the holders' pool and 0.345 to the treasury, which is exactly 150 : 100 : 20 of 270 bps; the pot was then claimed in full by the handle's owner with a real X sign in.

The delivery fee

  • HandleVaultFactoryV21.deliveryFeeBps is deployed at 500 (5%) (contracts/script/DeployV21.s.sol:265; contracts/DEPLOYMENTS.md "Factory on-chain state"), capped on chain at MAX_DELIVERY_FEE_BPS = 1_000 (10%) (contracts/src/v21/HandleVaultFactoryV21.sol:175), settable instantly by the owner with no timelock (setDeliveryFeeBps, contracts/src/v21/HandleVaultFactoryV21.sol:819).
  • 5% is the number the operator settled on 2026-09-12 on the previous v2 factory (raised there from a 200 (2%) deploy value, tx 0xbfaaae0d…02bc, .1 was deployed at 500 directly, to cover the measured cost of the fiat leg (about 1.5% for a PayPal instant transfer, about 1.3% for the bridge and swap hop at small size, plus gas and margin). It remains an owner-settable value with no timelock, so read deliveryFeeBps live before trusting this number** (see "How to verify" below) rather than assuming it can never move again.
  • The fee is paid to platformTreasury; the remainder goes to deliveryWallet (contracts/src/v21/HandleVaultV21.sol:634 to 665, .
  • Delivery is paid from the handle's own accrued pot, never from XLINK's own revenue. This is a reversal of an earlier decision: on 2026-09-11 the operator wanted XLINK to fund the X Money notification from its own fee share so the influencer's pool stayed untouched ; on 2026-09-12, after the live pipeline test, the operator reversed this explicitly: "We will pay the creators from the pot. We will not pay them from our own revenue" . The earlier own-fees model is superseded on this point; treat the pot-funded model as current.
  • There is no owner opt-in and no fee-free owner route to X Money in v2.1: optInDelivery, release and the bound-owner delivery branch were all deleted (contracts/src/v21/HandleVaultV21.sol:18-58). A verified owner who wants their wallet paid uses the one-shot claim, which pays 100% of the pot at no fee; a verified owner who wants X Money uses the same delivery path as everyone else, and pays the same 5% from the pot. requestDelivery is permissionless, has no minimum balance, and today no waiting window (deliveryDelay is 0; read it live); the guardian can cancelDelivery at any time as an incident brake (contracts/src/v21/HandleVaultV21.sol:593,621).
  • There is no delivery threshold and no auto-release in v2.1. v2 gated requestDelivery and autoRelease behind a per-vault threshold that the operator had already lowered to 1 unit on 2026-09-12; v2.1 removed autoRelease and the check itself (. The factory still exposes a defaultAutoReleaseThreshold getter (it reads 69,000,000 on the live factory) because the field is kept for storage-layout parity with AbandonmentManagerV21; no v2.1 vault reads it (HandleVaultV21.initialize, contracts/src/v21/HandleVaultV21.sol:235, takes no threshold). Money stays in the pot, whatever its size, until it is claimed, delivered, or swept as abandoned.

Contracts and addresses on chain 4663

Chain 4663 is Robinhood Chain, an Arbitrum L2, mainnet since 2026-07-01 (app/design/PILL-FACTS.md line 7). Free RPC used throughout this project: https://rpc.ordofi.network.

The current, live factory (v2.1)

ContractAddressDeploy txBlock
HandleVaultFactoryV210x16D36c555Eb5AB96a1159Cbc5B6d9582d3D7eb360xa1b08597efe6fe4210dadd0459677c8844fe747d5846e4edbaa58cdf883d927461,581,481
HandleVaultV21 implementation0x810d0a4A0B1d0c787819896C7f9aaB06C36cEd3d0xce948162c2dc6bbbb377a65994599e2bf0689d3e6409492c70c54b23eb80020b61,579,750
ReflectionDistributor0xD5587eaB8C3e44bD8772139B00123f0b656320160x62cca55cc69d469e5107639cf4c3fe373c5c0abebdab36b0a8a17969da2c356c61,579,753
FeeSplitter implementation0x6b47541a9771e518366dc06a3A12332AF02Bb6830x9e037430bd4345ab1b9ba941d5ff3ec45171376135db8df7adb871dba4e84a1d61,579,751
AbandonmentManagerV210xF414fE90210Ff176BBFC38C47e5Fc8d30B2690e00x6e77f6ed23e31580f6d153cb9c0bcf3b517ed46f466d8b3a8864e70d1535be6c61,579,748
ReflectionFeeMath0x353CEEF65a054E0dd2ceA0cB137FD57E0AA6Bc050x9db8f7314392b27bae8bb1dd9d1f52c19c26583c9b7cfa01d96eff7df510047261,579,746

Source: the deploy broadcast (raw transaction receipts), summarized with deployer nonces and bytecode checks in contracts/DEPLOYMENTS.md and contracts/deployments/v21-2026-09-13.json. Five contracts from an aborted first broadcast (deployer nonces 26 to 30) are orphaned and listed there; do not use them. Deployed 2026-09-13 as a fresh, parallel deployment: no v2 vault was migrated or upgraded, and the v2 factory keeps operating for the vaults it already has (contracts/src/v21/HandleVaultFactoryV21.sol:18-25).

Deployer, owner, guardian and treasury of the live factory are currently the same externally owned account, 0xf8B6322a0d6dfC2ecD7B89c0E7C5B4dA6376bD44 (owner, guardian and platformTreasury all read it; pendingOwner and pendingPlatformTreasury read zero). This is a known launch-day simplification, recorded as the top open item in reports/security/POSTURE-2026-09-13.md; rotation to fresh keys is scheduled after launch and will show up first in pendingPlatformTreasury / pendingPlatformTreasuryEta (7-day timelock) and pendingOwner. The identity oracle is a separate key, 0xF51EA9f6a6ca1e0d65F8Feb3E1E4517E4607649E, held only inside a Cloudflare Worker (see "The trust model" below). The delivery wallet is a distinct address, 0x62389156bB6E502690846F55f18fbC60916BD828, required distinct from the owner, guardian, treasury and oracle by the deploy script itself (contracts/script/DeployV21.s.sol:275, _requireDistinctDeliveryWallet). The delivery operator and the epoch keeper are one further distinct, gas-only key, 0xE585d13afDA7383A59fCF6406c6dEDFa257f7591, which can execute a delivery and publish an epoch but cannot choose where a single wei goes. Read owner, pendingOwner, guardian, platformTreasury, pendingPlatformTreasury, deliveryOperator and epochKeeper live before trusting any of these addresses (see "How to verify" below).

Bytecode verification: each of the six contracts' on-chain code was diffed against the compiled artifact's deployedBytecode after zeroing the immutable slots, and matched (contracts/DEPLOYMENTS.md, "Bytecode verification method"; instrument cast code plus a diff script; falsification condition: any byte outside the immutable slots differs). Sourcify source verification for the v2.1 addresses has not been submitted as of this writing, so the Sourcify endpoint returns no match for them yet; the previous v2 factory and implementation remain Sourcify exact-match. Check the code yourself:

bash
cast code 0x16D36c555Eb5AB96a1159Cbc5B6d9582d3D7eb36 --rpc-url https://rpc.ordofi.network
cast code 0x810d0a4A0B1d0c787819896C7f9aaB06C36cEd3d --rpc-url https://rpc.ordofi.network

The deployed FactoryConfig (v2.1), field by field

Read from the factory's live getters and the deploy script's _buildConfig (contracts/script/DeployV21.s.sol:243 to 270), matched against the field order in contracts/src/v21/HandleVaultFactoryV21.sol's FactoryConfig struct (line 444):

FieldLive valueMeaning
guardian0xf8B6…bD44instant oracle revoke, delivery cancel, distributor/splitter pause; read guardian live
oracle0xF51E…649Eidentity attestation and launch ticket signer
platformTreasury0xf8B6…bD44receives the claim-time platform share, the delivery fee and any abandoned-pot sweep
requiredPairToken0x5fc5…1d168 (USDG)every launch must pair against this
floorTaxBps100 (1%)creator tax floor and platform-share base
platformShareOfFloorBps2000 (20%)XLINK's share of the floor
deliveryWallet0x6238…D828where delivered funds land, after the fee
deliveryFeeBps500 (5%)delivery fee to the treasury; owner-settable, no timelock
deliveryDelay0 secondswaiting window before a request can execute; MIN_DELIVERY_DELAY is 0, MAX_DELIVERY_DELAY 7 days; owner-settable, no timelock, read live
deliveryOperator0xE585…7591only address allowed to call executeDelivery; set post-deploy by the owner, read live
epochKeeper0xE585…7591only address allowed to commit and push reflection epochs; set post-deploy by the owner, read live
firstBindWindow, keeperTipBps, keeperTipCapWei, defaultAutoReleaseThreshold3600 / 0 / 0.01 ETH / 69,000,000vestigial: kept so the factory's storage layout matches AbandonmentManagerV21's mirror; no v2.1 vault reads any of them (there is no bind window, no keeper tip and no auto-release in v2.1)

Not in the config struct but fixed at deploy as immutables: v2Factory 0xcB1C296F4b964cC03Ba89D4414Cf7B9BA1da117b (squat-prevention read on every createVault), abandonmentManager 0xF414fE90210Ff176BBFC38C47e5Fc8d30B2690e0, feeSplitterImplementation 0x6b47541a9771e518366dc06a3A12332AF02Bb683; and, behind a 7-day timelock, reflectionDistributor 0xD5587eaB8C3e44bD8772139B00123f0b65632016 (contracts/src/v21/HandleVaultFactoryV21.sol:151,157,162,193,299). The handle cooldown that v2 had is gone entirely, not floored: handleCooldown does not exist on the v2.1 factory (a call to it reverts), so a handle may launch any number of coins at any time (HandleVaultFactoryV21.sol:39-41).

The v2 factory (previous)

ContractAddressNotes
HandleVaultFactory (v2)0xcB1C296F4b964cC03Ba89D4414Cf7B9BA1da117bdeploy tx 0x17f008a82a5d46a10d061003c887945ab9a0fa312dbe1e0ae9c7de69ee6451d1, block 59,831,338
HandleVault implementation (v2)0x83bE7A2d8101E3aC87bAA0B5D5b9a0Ca0C67e54Ddeploy tx 0xeb2d9a73831b5509ccb977aa5d6df388fa1afe6eee4a714e07ecc30d5e61703e, block 59,831,315

Source: the deploy broadcast. Deployed 2026-09-11 and superseded by v2.1 on 2026-09-13; both contracts are Sourcify exact-match. The v2 factory still matters in two ways: the v2.1 factory reads its vaultOfHandle on every vault creation so no handle with a v2 vault can be recreated on v2.1 (HandleTakenOnV2), and the v2 vaults that exist keep their v2 mechanics (bind, release, auto-release, a 12-hour delivery delay) forever, since a vault's factory is fixed at creation. Its own rotation state is separate from the live factory's: its guardian was rotated to 0x22c73c5a2632E497e1EAFC06beFc2ae3770e38b8 and a new treasury 0x0758311D1Ccd468b280496cA07Af43B19a77BFee is proposed there under its 7-day timelock (pendingPlatformTreasuryEta on that factory reads 1789773436, 2026-09-18T23:17:16Z). New handle issuance on v2 is frozen operationally: the signer only signs tickets for the v2.1 factory (contracts/ROUND13-CUTOVER.md "Freeze v2 issuance").

USDG

0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168, 6 decimals, confirmed live on chain 4663 (; app/design/ACTIVITY-DATA-SOURCES.md section 2). Global Dollar, issued by Paxos Digital Singapore, MAS-regulated, 1:1 USD redeemable, natively on Robinhood Chain (app/design/PILL-FACTS.md line 6). approvedPairTokens(USDG) is true on the Pons factory.

Pons V2 (external, not built by this project)

ContractAddress
Pons V2 launch factory0x7eD598BcEf8bd9Edd8C97A195C6d13f40801EC7e
Pons V2 fee escrow0xd3AFEB2a57f70eF218Aa82451c51B2fb0416Ac9e
Pons V2 meme hook0xE5e702641Ea86F4ae6cC3cDaeD2B886f976Be044

Source: . launchFee was 0.0005 ETH; maxCreatorTaxBps was 1000; the launch-second anti-snipe tax is 9,900 bps (99%) decaying to zero over 3 seconds. Re-read these live before relying on any of them; Pons is an external protocol XLINK does not control.

The retired v1 factory, and why it is retired

ContractAddressDeploy blockDeploy tx
HandleVaultFactory (v1)0x1594B1BA75B793117003E70B2903E8BAECC4eCeD59,661,9600x2be115d3f49cad8dbefc8f30804a05adcd7d3e674cd046e4d0056dadcc3f5de0
HandleVault implementation (v1)0x416B8CAC08FdD0e109C3591243502914C582380859,661,960(same tx; v1's constructor deployed both in one transaction)

Source: the deploy broadcast, lines 132 to 133 ("the RETIRED v1 factory"), .

The v1 factory paired only against native ETH, used a single flat platformBps taken as a plain percentage of every claimed delta with no floor formula, a fixed 24-hour RELEASE_DELAY constant instead of a per-vault configurable window, allowed exactly one launch per vault ever, and had no launch tickets (only an allowlisted launcher could create a vault or launch a coin at all) and no community delivery path. It is what . It was superseded by "Fee model v2" (USDG-only pairs, the floor and split formula described above, a per-vault first-bind window, handle cooldowns, auto-release, community delivery, and oracle-signed launch tickets that let the general public launch without being on an allowlist; which v2.1 in turn replaced with the one-shot claim, no cooldown, no threshold, reflections and the abandoned-pot sweep described in this document. One vault still lives under the retired v1 factory: an E2E test coin under XLINK's own house handle, created 2026-09-10 before v2 existed -- not the real, official $XL, which has not launched (see the "Links and addresses" table above) (vault 0xa75b74d833B03f2eb477873090FC4a0628A13AE8, for X user id 2098113645448249347, handle xcoinpad). It was never migrated, because a vault's factory is fixed at creation. 's vault cache is scoped by factory address, but when the same handle has a vault on both factories the cache's own "v2 wins a clash" merge rule drops the older row entirely instead of showing both: as of 2026-09-12, GET /vaults lists only the v2 xcoinpad vault created below and omits this real, funded v1 xcoinpad test vault . The v2 factory's own first VaultCreated event fired 2026-09-12: a fresh, non-allowlisted wallet exercised the public launch-ticket path end to end, creating a second vault for the same handle, xcoinpad (vault 0x981830a74e2a74c28579c9a95e1bc40311690f9e, token "XLINK Test Coin" / XLT at 0x86a9929058e5A37Cf1639B279fE5b81dc357C081), confirmed live on chain (eth_getCode returns a 45-byte EIP-1167 clone of the v2 HandleVault implementation) and in GET /vaults . It was a controlled test of the launch mechanism, not an outside handle launching its own coin: on the v1 and v2 factories the only handle with a coin is XLINK's own test handle xcoinpad. Outside handles have since launched on v2.1 (see "Known limitations and open items"). The real, official $XL has not launched yet.

The trust model

What the identity oracle can and cannot do. The oracle is the one real, unavoidable trust dependency in this system, and in v2.1 it carries more weight than in v2: its signature on an Attestation is the sole on-chain authorization for a claim, and a claim pays the whole pot to the to address the attestation names, immediately (contracts/src/v21/HandleVaultV21.sol:543). There is no longer a contest window or a re-bind delay between a signature and a payout. The compensating controls are therefore all around the key: it is never held by a person or in application memory and lives only inside a Cloudflare Worker, signer.xl.money, which holds the oracle key as a Worker secret, only answers callers on an IP allowlist, requires a proof of the X sign-in bound to the to wallet before it will sign, authenticates every /sign call with an HMAC over the raw request body plus nonce replay protection and a rate limit, and fails closed (`, , ; reports/security/CUTOVER-v21-2026-09-13.md section 1, proof_enforced:true, caller_gating:"ip"). On chain, an attestation is single-use (a per-vault claimNonce), expires at its signed deadline, may not be dated more than one hour out (MAX_ATTESTATION_TTL), and is tied to the current oracleEpoch, so the guardian's instant revokeOracle invalidates every outstanding attestation in one transaction (contracts/src/v21/HandleVaultV21.sol:130,171,543-570; proven by test_ec14_guardianRevokeOracle_invalidatesAttestation`). A compromised oracle key, for as long as it went unrevoked, could sign a claim to an attacker's address for any launched pot with a balance; that is the honest statement of the residual risk, and it is why the signer hardening rounds and the key-custody checklist exist.

What only the handle's owner can do. Claim, and nothing else: there are no owner-only settings left on a v2.1 vault (setAutoReleaseThreshold, optInDelivery, optInConversion, updatePayoutAddress and release were all removed, contracts/src/v21/HandleVaultV21.sol:18-58). "Owner" is not stored on chain at all; owner returns the zero address for every v2.1 vault (:581). Ownership is proven fresh at each claim by the X sign-in behind the attestation.

The oracle and launch tickets. Two different EIP-712 structures are signed by the same oracle key: an Attestation (identity binding, verified against a specific vault's own domain) and a LaunchTicket (permission to create a vault or launch a coin, verified against either the factory's domain, for vault creation, or a specific vault's own domain, for launching a coin). A LaunchTicket names the exact (handleHash, xUserId, launcher) it authorizes, expires at a signed deadline, and is bound on chain to at most one hour of liveness after the moment it is actually consumed, regardless of how far out its signed deadline is (MAX_TICKET_TTL, contracts/src/v21/HandleVaultV21.sol:125, contracts/src/v21/HandleVaultFactoryV21.sol:180; the real staleness control is the signer's own issuance discipline, a 10-minute issuance default in and a 30-minute hard cap enforced inside the Worker (``)).

The delivery operator. Only factory.deliveryOperator, today XLINK's gas-only keeper key 0xE585d13afDA7383A59fCF6406c6dEDFa257f7591, may call executeDelivery. It can only ever move a requested vault's available balance to the delivery wallet snapshotted at request time, minus the snapshotted fee to the platform treasury; it cannot choose a different destination, cannot execute without a prior requestDelivery, and cannot execute before the snapshotted deliveryEta (contracts/src/v21/HandleVaultV21.sol:634).

The guardian. revokeOracle is instant, one transaction, zeroes the oracle for every vault simultaneously; appointing a new oracle is owner-only and behind a 7-day timelock, deliberately asymmetric (kill fast, appoint slow and in public) (contracts/src/v21/HandleVaultFactoryV21.sol:693,708,715). The guardian can also cancelDelivery on any vault at any time as an incident brake (contracts/src/v21/HandleVaultV21.sol:621), and pause the ReflectionDistributor and any FeeSplitter, which also blocks an abandonment sweep from executing while paused (contracts/src/v21/ReflectionDistributor.sol:384; FeeSplitter.sol:323).

Every other fund-affecting factory setting (the floor tax and its platform share, the platform treasury, the delivery wallet, the required pair token, the reflection distributor) sits behind its own 7-day timelock, propose then execute, so a live change is always public before it takes effect and never retroactively touches a vault that already locked in its own terms at launch (; contracts/src/v21/HandleVaultFactoryV21.sol:164-179,193). Two settings are deliberately instant and owner-only: deliveryFeeBps and deliveryDelay (a fee change cannot re-price a request already made, because requests snapshot both), and the two operational roles deliveryOperator and epochKeeper. The abandoned-pot path is owner-gated at both its markAbandoned and executeAbandonment steps and can be voided by the owner at any time (AbandonmentManagerV21.sol:373,539,823).

The allowlist is for XLINK's own keeper only. HandleVaultFactory.setAllowedLauncher and the two-argument createVault overload exist so XLINK's own infrastructure can pre-create or launch a vault without needing a signed ticket for itself; they are not how a member of the public gets a vault (contracts/src/v21/HandleVaultFactoryV21.sol:593,729).

The launch-ticket public path. Anyone else creates a vault or launches a coin through the ticket-taking overloads, gated only by a valid, unconsumed, oracle-signed LaunchTicket naming them (contracts/src/v21/HandleVaultFactoryV21.sol:598, contracts/src/v21/HandleVaultV21.sol:297). As of 2026-09-12, obtaining a ticket does not require signing in with X at all: connecting a wallet and signing a short-lived EIP-191 challenge is enough (GET /launch/challenge, POST /launch/ticket); X sign-in is required only later, to claim a vault as its owner (...)"). A prior finding that described public launching as "invite-only" or allowlisted was wrong and was corrected .

Audit history

Three internal review rounds (Phase 1, Phase 2, and a keeper/services review pass) plus six external audit rounds, five of them by three independent models (DeepSeek V4 Pro, GLM 5.3, Kimi K3) and the sixth by Kimi K3 alone, each round re-reviewing the actual diff from the previous round's fixes, are recorded in full in the audit record proves it) and contracts/AUDIT-ROUND4-VERIFY.md (an independent Opus verification pass with its own proof-of-concept tests for every claimed finding, contracts/test/Round4PoC.t.sol). Summary, oldest to newest:

  • Round 1 to 3 (2026-09-10), pre-v2, fixed contracts on the v1 fee model. Round 1's initial dedupe table alone had thirteen findings; rounds 2 and 3 each raised additional new findings of their own as they re-reviewed the actual diff from the previous round's fixes, narrowing to one shared residual by round 3. The most severe across all three rounds was that a maliciously-attested first bind, inside its own 24-hour window, could not actually be undone by a guardian oracle revoke because release never re-checked the epoch. Fixed with the "sticky contest" mechanism (bindEpoch versus the factory's live oracleEpoch, checked unconditionally until a release has genuinely succeeded once). All three auditors converged on this as the one residual after round 2 and confirmed it closed in round 3. Verdict: deploy for a five dollar dry run (the audit record.
  • Round 4 (2026-09-11), on the newly-written v2 contracts. GLM and Kimi independently found the same two highs: a coin's fee split could be silently re-priced by relaunching at a different tax, and a bound owner's community delivery could bypass the first-bind contest window entirely. DeepSeek's first pass returned no answer at all (a reasoning budget overflow) and, on retry, agreed with both highs. Sixteen findings total, all fixed or explicitly, individually accepted as a documented residual (the audit record.md`).
  • A re-check pass over round 4's own fixes (not the auditors, an Opus verifier reading the new source) found four more issues, three of them introduced or left open by round 4's own fixes, the most serious being that the new handle-correction function could be tricked into stealing a live, already bound handle's key rather than only clearing a genuinely abandoned one. Fixed by making that function clear-only: it can zero a stale mapping entry, and it can never write a destination (the audit record.
  • Round 5 (2026-09-11). All three auditors independently found that the delivery path's bound branch was still missing a pre-launch guard the unbound branch already had. DeepSeek separately found that the handle-correction function's own ticket check did not tie the ticket to the specific handle it was clearing, meaning a valid ticket for a caller's own handle could clear an unrelated vault's mapping. Both fixed; the platform's maximum possible share of the floor was also hard-lowered on chain from 5,000 to 2,000 basis points to make the "never more than 20% of the floor" promise a literal, unbypassable ceiling rather than only a constructor default (the audit record.
  • Round 6 (2026-09-11). Kimi K3 found a regression introduced by two of round 5's own fixes: a bound, standing delivery opt-in lost its pinned fee and destination after its first successful delivery, so a second delivery on the same opt-in would pay the zero address at zero fee, either bricking or burning funds. Fixed at the root (the pinned snapshot now survives execution on the bound path; only the unbound, one-shot request path clears its own snapshot). This was the last finding before the operator's go to deploy (the audit record.
  • v2.1 rounds 3 to 9 (2026-09-12 to 2026-09-13), on the new v2.1 contracts (vault, factory, FeeSplitter, ReflectionDistributor, AbandonmentManagerV21, ReflectionFeeMath): the same three-model external panel (DeepSeek V4 Pro, GLM 5.3, Kimi K3) re-reviewed each round's diff, with an Opus verification pass and a Fable plus Kimi K3 design duo before the build. Round 13 (the one-shot claim rewrite) closed at external round 9 with every finding fixed or individually dispositioned (contracts/audit/v21-r3-*.md through v21-r9-*.md, contracts/audit/v21-r9-disposition.md; the per-round fix suites are contracts/test/v21/R3Fixes.t.sol through R9Fixes.t.sol). The full suite at deploy was 351 passing forge tests including a live-fork lifecycle proof against the real Pons contracts (contracts/script/E2E-FORKPROOF-2026-09-13.md).
  • Every round's instrument is named. Every "fixed" row in the audit record points at a specific fork test that failed before the fix and passes after it; the full fork suite (149 tests for the v2 suite at its last recorded run, the audit record "Round 6 dispositions"; 351 for the v2.1 suite at deploy) is re-run after every single fix, not just at the end.
  • K3 has not reviewed the version of this document, the site copy, or anything built after the contract audit rounds above. Everything in, and the app was reviewed by Opus acting as an independent critic (, ), not by the external three-model panel; treat that as a lower bar of scrutiny than the contracts themselves received.

The X Money receive flow, as verified

Verified live with a real one-dollar send on 2026-09-12 . Sender side: "You sent $1 to @handle. They're not using this feature yet," a transaction detail screen reading "Awaiting access to Money," a Cancel button, and a stated 14-day expiry after which an unaccepted payment refunds automatically. Receiver side, if not already on X Money: "<Sender> sent you $1, continue before it expires," an Accept button whose acceptance is agreeing to the Cross River Bank stored value account agreement, then identity verification (legal name matching a government ID), then the payment reads "+$1," Completed, with the sender's note shown verbatim underneath, plus a fifteen dollar welcome gift for onboarding during the current promotion and a native "Share to X" button that opens a composer with a receipt card (amount, "received from <Sender>," the note, elapsed time, both avatars). There is no automatic public artifact from X itself; the only public trace is what the receiver chooses to share, or what XLINK's own bot posts once it independently confirms the send.

Consequence for product copy: the sender's own display name and avatar appear on every screen the receiver sees and on the shared receipt card. During the live test on 2026-09-12 the sender still showed as "Xmemes" with no avatar because the brand rename was pending; the account has since been renamed to @X_Link_Money with a profile image, so the receiver now sees the brand name and avatar on every screen and on the receipt card .

Eligibility: who gets the X Money delivery option

Every real X handle is launchable, unconditionally . What differs by handle is only whether the community "deliver to X Money" option is offered at all, because X Money itself is a US product. GET /handles/:handle/profile derives an advisory xMoneyEligibility of us, non_us, or unknown from an unofficial signal, X's own "account based in" panel, mirrored (with no authentication and no official support) by api.fxtwitter.com, since the official X API v2 has no country field at all (). A us result shows the delivery option, live as of 2026-09-13 (the request is submitted on chain, executed by the keeper, bridged to PYUSD at PayPal by the rail, and finished by the operator's manual X Money send); non_us and unknown show it disabled with an explanatory caption. This gate never touches the launch path itself: it only decides whether the X Money delivery button is offered; the on-chain exit (sign in with X, one-shot claim to your own EVM address) works identically for every handle regardless of country (: "eligibility must gate only the X Money leg, never the launch").

What is not automated: the human taps

Three manual steps remain in the actual money path, and are intentionally never scripted:

  1. Selling PYUSD for US dollars inside PayPal. PayPal has no API for this and no auto-convert setting for received crypto .
  2. Moving the resulting US dollar balance from PayPal into X Money, either by waiting for PayPal's own daily automatic transfer or by tapping its instant transfer option. PayPal has no self-withdrawal API for a business or consumer account (: "NO API for a business/consumer account to withdraw its own balance to its own bank").
  3. Sending the X Money peer to peer payment itself, with its note, from the operator's phone or the /ops/pad console. There is no X Money API at all (: "It has no API and X's ToS bans scripted access"). This is also a deliberate product choice, not only a technical limitation: the operator has repeatedly rejected scripting or browser-automating the financial apps themselves on the brand's own accounts, citing the real risk of PayPal or X freezing a KYC'd account for automated access (: "browser automation of PayPal and device automation of the X app violate their terms and can freeze the KYC'd money accounts").

Everything upstream of step 1 (the on-chain delivery execution, the bridge, the swap into PYUSD) runs unattended now that the gates above are on; no v2.1 on-chain delivery has been requested or executed as of this writing (the only executed on-chain delivery is the 2026-09-12 v2 test, and the fiat rail was proven standalone on 2026-09-13). Everything from step 1 onward is, and is meant to stay, a human tap; a WhatsApp alert to the operator fires per delivery request so the taps happen promptly.

Known limitations and open items

  • Third-party handles have launched and claimed, but the numbers are launch-day small. The first coin launched through the public site by an outside handle (2026-09-13, with reflections on) accrued real fees, split them exactly as the contracts compute, and its owner claimed 2.588 USDG with a real X sign in and the keeper-paid one-shot claim; a second outside handle's pot exists and is unclaimed. Test artifacts from the build (XLINK's own xcoinpad vaults and test coins on the v1, v2 and v2.1 factories) are being removed from the site's indexes and may still appear in GET /vaults while that cleanup lands. Do not describe the platform as having broad third-party usage; read GET /vaults and GET /activity fresh instead.
  • The end-to-end pipeline has been proven on the previous (v2) factory; on v2.1 the claim leg is proven and the delivery/rail legs are enabled but not yet exercised on-chain. The X Money last mile remains a human send each time. The ten-dollar run was the operator personally moving USDG through the bridge and swap into PYUSD, then through PayPal to X Money, ending with a real X Money notification reading "You received $9.36 from PayPal" . On the v2 factory, on 2026-09-12 at 04:19Z, executeDelivery ran unattended on a test wallet (tx 0xaec5d55e…5285): 0.029915 USDG left the vault, the delivery wallet received 0.028420 and the treasury 0.001495, exactly the 5.00% delivery fee . On v2.1, the fiat rail was exercised standalone on 2026-09-13 (~9 USDG bridged USDG→PYUSD to PayPal's deposit address by the operator), but no on-chain executeDelivery has run yet; the claim leg was proven the same day by a real handle owner (2.588 USDG paid in one shot, tx 0xbc38471d…).
  • The brand's X account is renamed. Since 2026-09-12 the brand runs as @X_Link_Money (https://x.com/X_Link_Money). The v1 xcoinpad test vault stays bound to the on-chain handle xcoinpad forever (a vault's handle is fixed at creation and was never migrated); a relaunch of the platform coin on v2.1 is a manual operator decision and has not happened as of this writing; the "Links and addresses" row shows no address until $XL launches.
  • /docs can briefly disagree with /llms.txt and /llms-full.txt after a rename or relaunch, and neither is guaranteed to match chain state the instant it changes. /docs is statically generated (next build reports it ○ Static): its withLiveConfig patch (app/src/app/docs/docs-content.ts) compares the handle and $XL address a build was configured with against today's known values once, in Node, during that next build; it never runs at request time, so /docs is only as current as its most recent production build and deploy. llms.txt/llms-full.txt are separate static files served byte-identical to this document as committed, and only pick up a rename once someone edits this file's "Links and addresses" row and re-copies it to llms-full.txt. So after a rename or relaunch, this file, /docs, and llms.txt/llms-full.txt can each be current as of a different moment for a while: this file as of its last edit, /docs as of its last build and deploy, and llms.txt/llms-full.txt as of their last copy from this file.
  • The community delivery leg has a real, verified, unresolved regulatory exposure. Converting and sending an unaffiliated handle's own accrued funds to them via X Money, for a fee, is money transmission under 31 CFR 1010.100(ff)(5) with no natural-person carve-out that comfortably fits recurring, for-profit activity, and 18 U.S.C. 1960 does not require knowledge that a license was needed . The operator has parked this question rather than resolved it, pending the product working end to end first . Nothing in this document should be read as legal clearance for the delivery leg.
  • The rail executor and delivery automation are enabled and running unsupervised under size caps since 2026-09-13. Per-execution and per-day caps (see the keeper table above), a per-request WhatsApp alert, a DELIVERY_HALT file that stops execution instantly, and the fact that the delivery operator key cannot redirect funds are the controls. Open items carried from the enabling review: an unexpected-outbound alert on the delivery wallet before aggregate pots exceed about $1k, a reconciliation watch on early real deliveries, and moving the delivery key off the box into a policy-constrained signer Worker (ops/delivery-signer/DESIGN.md). The MSB caveat in the previous bullet is unchanged by any of this.
  • No platform coin ($XL) has launched yet, so there is no holder count, lifetime trading volume or live price to show for it, and none of the available third-party indexers (Dexscreener, hoodscan) have anything indexed for it; this is stated plainly rather than guessed at (app/design/ACTIVITY-DATA-SOURCES.md section 4).
  • There is no in-vault ETH-to-USDG conversion in v2.1. v2's convertToUSDG and its opt-ins were removed from the vault (contracts/src/v21/HandleVaultV21.sol:18-58); the factory still carries the timelocked conversion config for layout parity, and conversionEnabled reads false. v2 vaults keep their (disabled-by-default) conversion leg.
  • Reflections are live (see "Reflections: the holders' share, live" under "The fee model"). What is still young: the multiplier parameters are the operator's launch-day configuration and may be tuned; holder accounting is off chain (balances snapshotted from Transfer logs each epoch), and the published root is what makes the keeper's allocation auditable after the fact, not what prevents a dishonest one; no third-party indexer shows reflection payouts yet, so the ReflectionDistributor's Pushed / Claimed events are the source of truth.
  • Abandoned pots. A pot with no claim, no fee collection on any of its coins and no reflection claim on any of its pools for 14 days (ABANDON_INACTIVITY) may be marked abandoned by the factory owner (markAbandoned, an on-chain notice event), which opens a 14-day public notice window (ABANDON_NOTICE_WINDOW); after it the owner may executeAbandonment, which re-verifies every liveness signal and exact balance snapshots, and only then opens a 72-hour drain window (DRAIN_TTL) in which the permissionless sweepAbandonedVault pays the pot to platformTreasury and nowhere else, and ReflectionDistributor.sweepAbandonedPool does the same for that pot's holder pools. A claim, a delivery request, any fee activity, a holder's pull-claim, or a one-wei balance change voids the mark. This is a genuine privileged drain path and the "non-custodial" framing above does not apply to a pot in that state; XLINK will assess abandonment manually from its own records and never sweep a pot that shows any activity. No pot has been marked as of this writing (contracts/src/v21/AbandonmentManagerV21.sol:184-186,373,539,647,673; ; read markAt(vault) and abandonedFlag(vault) on the factory live).
  • Two marketing figures on the live home page are explicitly not verified claims. "1M+ users on X" and "100,000+ X Money users" were authorized once by the operator as marketing copy for exactly two stat pills and are documented as such precisely so nobody mistakes them for sourced numbers elsewhere (app/design/PILL-FACTS.md, "Amendment, 2026-09-12").
  • Where this document and a live /status or on-chain read disagree, trust the live read. document can go stale between edits; a chain read or a live endpoint cannot.

How to verify each claim yourself

bash
# Confirm the current factory and its live configuration.
F=0x16D36c555Eb5AB96a1159Cbc5B6d9582d3D7eb36
RPC=https://rpc.ordofi.network
for fn in "implementation(address)" "oracle(address)" "oracleEpoch(uint256)" \
  "guardian(address)" "owner(address)" "pendingOwner(address)" \
  "platformTreasury(address)" "pendingPlatformTreasury(address)" "pendingPlatformTreasuryEta(uint256)" \
  "deliveryWallet(address)" "deliveryOperator(address)" "epochKeeper(address)" \
  "floorTaxBps(uint16)" "platformShareOfFloorBps(uint16)" \
  "deliveryFeeBps(uint16)" "deliveryDelay(uint256)" \
  "reflectionDistributor(address)" "abandonmentManager(address)" \
  "feeSplitterImplementation(address)" "v2Factory(address)" "requiredPairToken(address)"; do
  echo "$fn: $(cast call $F "$fn" --rpc-url $RPC)"
done
# Expect: implementation 0x810d0a4A0B1d0c787819896C7f9aaB06C36cEd3d,
# reflectionDistributor 0xD5587eaB8C3e44bD8772139B00123f0b65632016,
# abandonmentManager 0xF414fE90210Ff176BBFC38C47e5Fc8d30B2690e0,
# v2Factory 0xcB1C296F4b964cC03Ba89D4414Cf7B9BA1da117b, deliveryFeeBps 500, deliveryDelay 0.

# Count how many vaults exist under v2.1 when you run this.
cast logs --from-block 61581481 --to-block latest \
  --address 0x16D36c555Eb5AB96a1159Cbc5B6d9582d3D7eb36 \
  "VaultCreated(uint256,bytes32,address,string)" \
  --rpc-url https://rpc.ordofi.network

# Confirm no pot has been marked abandoned (an empty result means none).
cast logs --from-block 61581481 --to-block latest \
  --address 0x16D36c555Eb5AB96a1159Cbc5B6d9582d3D7eb36 \
  "AbandonMarked(address,uint256,uint256)" \
  --rpc-url https://rpc.ordofi.network

# Confirm the live bytecode matches the compiled artifacts (method in contracts/DEPLOYMENTS.md).
cast code 0x16D36c555Eb5AB96a1159Cbc5B6d9582d3D7eb36 --rpc-url https://rpc.ordofi.network
cast code 0x810d0a4A0B1d0c787819896C7f9aaB06C36cEd3d --rpc-url https://rpc.ordofi.network
cast code 0xD5587eaB8C3e44bD8772139B00123f0b65632016 --rpc-url https://rpc.ordofi.network

# The previous v2 factory and implementation remain Sourcify exact-match.
curl -s "https://sourcify.dev/server/v2/contract/4663/0xcB1C296F4b964cC03Ba89D4414Cf7B9BA1da117b"
curl -s "https://sourcify.dev/server/v2/contract/4663/0x83bE7A2d8101E3aC87bAA0B5D5b9a0Ca0C67e54D"

# Confirm the claim, delivery and sweep properties on a fork of the live chain.
cd contracts && forge test --match-path "test/v21/*" \
  --match-test "test_claim_fullBalancePayout_pendingPlatformShareReserved|test_ec14_guardianRevokeOracle_invalidatesAttestation|test_sweepAbandonedVault_onlyFactoryCanCallVaultSweep|test_fork_squatPreventionAgainstRealV2Factory"

# Re-run the full v2.1 suite yourself (contracts/README.md "Tests" under "v2.1").
cd contracts && forge test --match-path "test/v21/*"

# Confirm the retired v1 factory and the v1 xcoinpad test vault.
cast call 0xa75b74d833B03f2eb477873090FC4a0628A13AE8 "factory(address)" --rpc-url https://rpc.ordofi.network
# Expect 0x1594B1BA75B793117003E70B2903E8BAECC4eCeD, the retired v1 factory, not the v2.1 address above.

# Confirm services and the signer are live and configured, without any secret in the request.
# (the signer's /health answers only from allowlisted callers; from elsewhere expect 403, which
# is itself the caller-gating working)
curl -s https://api.xl.money/status
curl -s https://signer.xl.money/health

# Read the keeper's view of the live factory (read-only, no signer used). The three env vars
# are the factory address and deploy block from "Contracts and addresses" above plus the same
# public RPC used throughout this document, not secrets; the script has no default and errors
# without them.
HANDLE_VAULT_FACTORY=0x16D36c555Eb5AB96a1159Cbc5B6d9582d3D7eb36 \
FACTORY_DEPLOY_BLOCK=61581481 \
RPC_URL=https://rpc.ordofi.network \
node  --json

Every command above reads public chain state or a public endpoint; none requires a key or a secret. If any answer disagrees with a number in this document, the live answer is correct and this document is stale on that point.

Community

$XL · Robinhood Chain (chain id 4663)

Announced at launch