> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cryptocheckout.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Settlement model

> Two rails, one pool, and the design constraints that produced them. Locked 2026-06-18.

Authoritative specs: `docs/superpowers/specs/2026-06-18-settlement-rails-and-finality.md` and `2026-06-04-phase1-pool-settlement-design.md`.

## The shape

```
CONNECT RAIL                          DEPOSIT RAIL
customer's wallet signs               plain transfer / QR / CEX withdrawal
MerchantPool.deposit()                        │
        │                                     ▼
        │                             per-invoice forwarder (CREATE2)
        │                                     │  keeper deploys + sweeps 100%
        ▼                                     ▼
        └──────────►  MERCHANT POOL  ◄────────┘
                            │
                            ▼  distribute()  — permissionless
                   99 / 0.75 / 0.25 to on-chain-committed recipients
                            │
                            ▼  claim()  — pull pattern
                     merchant · treasury · partner
```

Both rails settle into the same pool. Neither is a fallback for the other; they serve different customers.

## Why two rails

The connect rail alone would be simpler and free for the platform. It is insufficient because a large share of real crypto payments originate from **exchange withdrawals**, where the customer has no connected wallet and the sending address belongs to a shared omnibus hot wallet. Refusing those payments refuses a large fraction of the market.

Accepting them forces three things that shape the entire system:

<Steps>
  <Step title="A unique address per invoice">
    The only reliable way to attribute an anonymous inbound transfer is to give each invoice its own address. That address must be computable and displayable before it has any code, which means CREATE2 and counterfactual derivation.
  </Step>

  <Step title="Platform-sponsored gas">
    Nobody is present to sign the sweep. The keeper must deploy the forwarder and move the funds, paying native gas. Everything in [Economics](/economics/who-pays-what) follows from this.
  </Step>

  <Step title="No safe refund target">
    Funds arriving from an omnibus hot wallet cannot be returned to the sender. This is what killed the on-chain refund window. See [Finality and refunds](/settlement/finality-and-refunds).
  </Step>
</Steps>

## The pool

`MerchantPool` is one contract per merchant per chain. It is **immutable and ownerless** — no admin, no upgrade path, no pause. Its constructor arguments include the merchant recipient, treasury, partner, and the basis-point splits, so those values are part of the CREATE2 preimage. The pool's address commits to its own payout behaviour.

Two consequences:

* Changing where a merchant's money goes requires deploying a **different pool at a different address**. It cannot be done quietly.
* The same merchant has the **same pool address on all seven EVM chains**, because the init code is byte-identical across them. TRON derives separately because it uses a `0x41` CREATE2 prefix rather than `0xff`.

`MerchantPool.sol` exposes exactly three external functions:

```solidity theme={null}
function deposit(bytes16 paymentId, IERC20 token, uint256 amount) external nonReentrant;
function distribute(IERC20 token) external nonReentrant;
function claim(IERC20 token, address account) external nonReentrant;
```

<Info>
  There is no `receive`, no `fallback`, and no token-received hook. A forwarder sweep is a plain ERC-20 transfer to the pool address and **does not execute pool code at all**. The pool reads `balanceOf(address(this))` at distribute time. This is not a detail — it determines the economics of cloning and the load profile of the whole system.
</Info>

## Counterfactual deployment

Both pools and forwarders are computed at quote or setup time and deployed lazily.

| Artefact  | Salt keyed on     | Deployed when                                                                   |
| --------- | ----------------- | ------------------------------------------------------------------------------- |
| Pool      | merchant identity | first use — moving to merchant-paid, see [Integration](/integration/quickstart) |
| Forwarder | `paymentId`       | after funds are observed at the address                                         |

The forwarder is only ever deployed **after** funds arrive, which means it cannot be griefed into existence. The pool is different: `deposit()` is a contract call and reverts against an address with no code, so the connect rail requires a deployed pool. The deposit rail does not — a sweep into an undeployed pool is a plain transfer that becomes distributable the instant the pool exists.

## Phase 1 scope

Phase 1 is **stablecoin-only**. USDC, USDT, and EURC.

Token swapping at checkout — `RouterFee.payWithSwap`, `payNative`, `accept_any_token`, the multi-token picker, and Uniswap routing — is **Phase 2**. Those contracts are deployed and the code paths exist, but they are an opt-in path, not the default. Any document describing `RouterFee` as *the* payment path predates the 2026-06-18 lock.

<Warning>
  `RouterFee.payWithSwap` carries a known encoding bug: `V3_SWAP_EXACT_OUT` is set to `0x09`, which is V2's opcode. It requires a redeploy to fix and is Phase-2 only. Do not build on that path.
</Warning>

## Tracking

The settlement rail work is tracked in Linear under the **Settlement v3 — accumulating pool rail** project. The retired WS1–WS12 workstream model no longer exists.
