The contract
LuxxonSettlement v3 is a prepaid deposit-pool router. The Solidity
source lives at contracts/src/LuxxonSettlement.sol in the project
repository.
Deployed: Base Sepolia at
0xa748C178df47c2DA2227C247293943713eB65a26.
Mainnet bringup is the next step — same bytecode, same constructor
params, different RPC.
The shape is prepaid pool + meter-bounded debit:
- Checks
settled[sessionId]to refuse double-spending the same session. - Enforces the meter invariant
toAmount + feeAmount ≤ ratePerSecond × chargeableSeconds. Even a fully-trusted relayer can’t bill above the rate it quoted the consumer off-chain. - Debits the consumer’s pool balance and refuses underflow.
- Transfers USDC to the operator and to
platformWallet(the contract’s stored fee recipient — never a settle parameter, so the fee can’t be misrouted). - Emits
Settled(sessionId, from, to, toAmount, feeAmount, rate, seconds).
settleBatch(BatchEntry[]) variant for amortizing
gas across multiple sessions (up to 100 per tx).
Trust model
The pool model shifts the trust boundary versus the previous EIP-712 per-session signature flow:- Before (v2.1): the consumer signed each session’s bounds. A compromised relayer could only settle within those bounds — but the consumer paid a wallet popup per session.
- Now (v3): the consumer signs the deposit once. A compromised relayer can drain up to the current pool balance before the consumer notices and withdraws. The contract still enforces the meter invariant + the platform fee recipient, so a rogue relayer can’t reroute funds — only over-bill within the pool.
withdraw path is intentionally not gated by
whenNotPaused — the consumer always has an escape valve.
The relayer
Consumers don’t submit on-chain. The flow is:- Consumer calls
USDC.approve(spender=settlement, max)once. - Consumer calls
LuxxonSettlement.deposit(amount)— funds the pool. From this point on no further wallet popups are required for sessions. - At session
/end, the relayer worker (lives inapps/lx-relayer) reads the ENDED session and submitssettleFromPool(...)from its KMS-backed key. - The relayer appends the Coinbase Base Builder Code
(
bc_grllwffr) to the calldata so the volume is attributed to Luxxon in Base’s builder rewards program.
State machine
GET /settlements/:sessionId:
Math
cleanSeconds and
ratePerSecondMicroUsdc are public.
What’s live, what’s not
| Layer | Status |
|---|---|
| Contract source + foundry tests (24 passing) | Live |
| Contract deploy + relayer wired | Base Sepolia |
| Pool deposit / withdraw (off-chain) | Live |
Pool-balance pre-flight check at /sessions create | Live |
Relayer worker (apps/lx-relayer) | Live, e2e tested on Sepolia |
| Coinbase Base Builder Code attribution | Live (bc_grllwffr) |
| Mainnet deploy | Pending |
| Per-workspace fee overrides | Roadmap (today fee is platform-global at 15%) |
Until mainnet bringup,
txHash values you see point to
Base Sepolia. The wire protocol
does not change between testnet and mainnet.