Zero-Gas Trading: How the THRYX Paymaster Self-Funds From Protocol Revenue

10 min read

Gasless trading is the single biggest UX advantage THRYX has over other Base launchpads. New users sign up with email and password, get a managed wallet, and buy their first meme coin without ever holding ETH. No faucet, no bridge, no exchange signup. The paymaster makes this possible, and it needs to be self-sustaining or the protocol bleeds to death. This post explains how the plumbing works.

The relay-Diamond-paymaster loop

Every user action on THRYX (launch, buy, sell, claim) follows the same path. The user signs an EIP-712 typed-data message in the browser. The signature is sent to a Cloudflare Worker relay at thryx-relay.thryx.workers.dev. The relay submits the signed message to the Diamond contract on Base, paying gas from its own ETH balance. The Diamond executes the action and reimburses the relay from s.paymasterEthBalance in the same transaction. The relay's wallet (0x888F4365eBcF38B6213dB489F68F66427E2E11B7) never goes negative because every transaction that costs gas also reimburses that gas.

Why Base L2 economics make it work

A swap on Base costs approximately 300,000 gas at around 0.01 gwei, which works out to 0.000001-0.000003 ETH per transaction (roughly $0.002 at current ETH prices). A 1% swap fee on a $2 trade generates $0.02 in protocol revenue. The protocol earns 10x more per trade than it spends on gas. On Ethereum mainnet, where a swap costs $5-20 in gas, this model would be impossible. On Base, the ratio flips so hard that gas sponsorship is not charity; it is a rounding error in the fee structure.

MetricValue
Typical swap gas~300,000 units
Base gas price~0.01 gwei
Cost per swap~0.000003 ETH ($0.006)
Gas grant per new user0.00001 ETH (one-time)
Grants per 0.001 ETH~100 users
Fee revenue per $2 trade~$0.02 (1% fee)
Revenue/cost ratio~3-10x per trade

Paymaster keeper: the main refill loop

The paymaster-keeper (server/lib/paymaster-keeper.js) runs every 5 minutes. It reads the Diamond's paymasterEthBalance storage slot. If the balance is below a target floor, it sells Diamond-owned NEW for ETH through the v3 pool. The critical design challenge: selling too much NEW in one transaction crashes the pool price. Selling too little leaves the paymaster underfunded. The keeper solves this with binary search.

The binary search works by halving the sell amount until the staticCall simulation succeeds and returns a non-zero ETH amount. Starting from min(50M NEW, 5% of Diamond's NEW balance), the keeper tries a static call. If it reverts (pool cannot absorb), it halves the amount. If it succeeds but the ETH output is below the gap to fill, it doubles. The search converges in 3-5 iterations, typically finding an amount that fills exactly the ETH deficit without moving the pool tick more than a few hundred units.

The auto-rescue watchdog

The paymaster-auto-rescue job (server/jobs/paymaster-auto-rescue.js) runs every 2 minutes, independent of the main keeper. It has a single job: if Diamond ETH drops below 0.001 ETH, try to fix it immediately. The rescue has two steps executed in sequence:

  1. Sell NEW for ETH via Diamond.sellNewForEthFor(). Same binary-search sizing as the main keeper, capped at 50M NEW per rescue. Static-call first; if the pool cannot absorb, skip to step 2.
  2. Sweep pending hook fees via Diamond.sweepHookFees() + reconcilePaymasterEthBalance(). Anti-sniper hooks accumulate protocol fees as WETH. Sweeping pulls that WETH to the Diamond and reconciles the paymaster's stored balance with the actual ETH held.

Both steps respect the staker-debt guard: if Diamond WETH is at or below the total owed to NEW stakers, the rescue skips the sell step rather than risk making staker claims insolvent. An exponential backoff kicks in after 3 consecutive pool failures (the pool literally cannot absorb any sell), spacing retries out to a maximum of 1 hour apart.

Private mempool protection

Every keeper transaction routes through Blink Labs' private RPC (base.blinklabs.xyz). The makePrivateWallet() wrapper overrides sendTransaction to submit signed raw transactions via eth_sendPrivateTransaction, which delivers them directly to block builders without exposing them in the public mempool. This prevents sandwich bots from seeing predictable paymaster sells and front-running them. If BLINK_BASE_PRIVATE_RPC is not set, the auto-rescue disables itself entirely rather than broadcasting keeper actions publicly.

The gas grant model

New users receive a one-time gas grant of 0.00001 ETH. This covers approximately 3-5 meta-transactions. After the grant is consumed, the relay model takes over: the relay pays gas and gets reimbursed from paymasterEthBalance per-transaction. The grant exists because the very first transaction from a new wallet has no prior ETH to reimburse with. After that first action, the Diamond holds enough fee revenue from the user's first trade to self-sustain.

What happens when the paymaster runs dry

The paymaster has never fully drained in production, but the system is designed for it. If paymasterEthBalance hits zero: (1) the auto-rescue fires within 2 minutes and attempts a sell + sweep, (2) the solvency-monitor detects the low balance and emails the admin, (3) the paymaster-keeper's next 5-minute cycle attempts a larger sell. Users experience a brief window where transactions may fail with an "insufficient paymaster balance" error. In practice, the auto-rescue resolves the gap before most users notice. The lowest the paymaster has dropped in production was 0.00004 ETH during the 2026-05-24 staker insolvency incident, and the rescue recovered it within one cycle.

Revenue flow diagram

User trades $2 of tokens. SwapFacet charges 1% fee ($0.02). Protocol keeps 30% ($0.006 as WETH). FeeRouterFacet splits: 40% to stakers, 20% to burn queue, 25% to treasury, 5% to paymaster ($0.0003), 10% to insurance. Meanwhile, the relay spent $0.002 in gas. The paymaster's direct 5% cut only covers $0.0003 of that $0.002 gas cost. The remainder comes from the main paymaster-keeper selling Diamond-owned NEW. Net: the protocol earns $0.006 and spends $0.002 on gas. $0.004 profit per $2 trade, after gas sponsorship.

Frequently asked questions

Frequently asked

Does the user ever pay gas on THRYX?
No. Every transaction (launch, buy, sell, claim, stake, unstake) is gas-free for the user. The Cloudflare Worker relay pays gas and is reimbursed by the Diamond's paymaster balance. The user needs no ETH in their wallet at any point.
What if the NEW/WETH pool has no liquidity and the keeper cannot sell?
The auto-rescue falls back to sweeping hook fees (WETH already on the hooks from anti-sniper activity) and reconciling the paymaster balance. If both fail, exponential backoff prevents the keeper from hammering a broken pool. The solvency-monitor emails the admin. The protocol has enough runway (insurance fund + accumulated hook fees) to bridge multi-hour gaps.
Why not use ERC-4337 account abstraction instead?
THRYX predates widespread Base AA infrastructure. The relay+paymaster model achieves the same user-facing result (gasless transactions) with simpler contract logic. The Diamond's PaymasterFacet is 300 lines of Solidity vs the thousands of lines in a full ERC-4337 entrypoint + paymaster + bundler stack. If Base ships native AA with equivalent simplicity, migration would be considered.
How much ETH does the paymaster consume per day?
At current trading volumes (~50-100 trades/day), the paymaster consumes approximately 0.0001-0.0003 ETH/day in gas. This is replenished by the 5% FeeRouter cut plus the keeper's periodic NEW-to-ETH conversions. The system is self-sustaining at any volume where average trade size exceeds ~$0.50.
Can I verify the paymaster balance on-chain?
Call paymasterEthBalance() on the Diamond (0x2F77b40c124645d25782CfBdfB1f54C1d76f2cCe). This returns the stored balance in wei. The actual ETH balance of the Diamond address (readable via eth_getBalance) may be slightly higher due to unreconciled deposits. The reconcilePaymasterEthBalance() function syncs them.

Related Posts

Create Your Token