intentional.soDocs

Reservoir protocol

Factoring for onchain claims.

Sell a future payment. Get paid today.

In one sentence

A factor buys your pending withdrawal claim, pays you now, and accepts the timing and impairment risk of the eventual protocol payout.

The problem

Many DeFi positions are claims on future payments: a Lido withdrawal request, or an ERC-7540 redemption request waiting for the next epoch. While a claim sits in the queue it cannot be spent, and it cannot be sold on a normal exchange.

You holdA claim on 2.6 ETH, arriving in ~5 days
You get~2.59 ETH, right now
The factorWaits, then collects the 2.6 ETH

Why this cannot just be a swap

Fungible-token orders name an ERC-20 sellToken. A withdrawal claim may instead be an NFT or an entry in vault storage, so ordinary ERC-20 execution cannot express every route. Reservoir provides claim-specific acquisition and settlement postconditions.

The completed mainnet proof originated a new Lido withdrawal from liquid stETH and paid the seller atomically. Buying an already-created unstETH is under development. The ERC-7540/8161 path is reference-only because no production ERC-8161 vault is used in this repository.

Payment happens if and only if the claim is secured—in the same transaction.

Flow

How it works

Four steps, one onchain transaction.

  1. 01
    Quote

    The factor signs an EIP-712 price offer offchain. It has a nonce and deadline and remains valid for at most 15 minutes.

  2. 02
    Accept

    The named seller submits the quote. A quote signed for one seller cannot be used by another.

  3. 03
    Settle atomically

    The contract verifies the quote, acquires and measures the claim, withdraws the exact payment, and pays the seller. If one step fails, all of it reverts.

  4. 04
    Collect

    The factor waits for finalization and collects the actual queue payout. Timing and impairment risk stay with it.

Settlement flow

Funds flow of one Lido factoring settlementInside a single transaction: the seller sends stETH to the Lido adapter, the adapter sends the measured amount to the Lido withdrawal queue, and the queue mints the withdrawal claim directly to the factor. In the opposite direction, the Aave StataWETH vault releases only the exact shortfall to the funding account, which pays the exact WETH amount to the seller. Days later, outside the transaction, the queue pays the factor the finalized ETH amount, which may be impaired.ONE TRANSACTION · ALL OF IT OR NONE OF ITSellerHOLDS STETHLido adapterMEASURESLido queueCANONICALFactorHOLDS CLAIMFunding accountPAYSAave StataWETHCANONICAL1 stETHmeasured delta2 stETHexact measured3 unstETHminted to factor4 WETHexact shortfall5 WETHexact payment6 days later, when the queue finalizesFinalized ETHFACTOR COLLECTS
The claim moves right, the money moves left, and the outline is the transaction. Only the sixth leg happens outside it — that wait is what the discount pays for.

Three claim paths, stated separately

Proven on mainnet

The claim does not exist yet

The seller holds stETH and wants ETH now. During settlement, the adapter creates a new Lido withdrawal ticket owned by the factor while WETH is paid to the seller.

seller stETH
    ↓
new Lido withdrawal ticket → factor
WETH payment               → seller
Under development

Existing unstETH

The seller already owns a Lido withdrawal NFT. The exit adapter must acquire that exact token and verify ownership, request amount, share amount, and claimed state before any payment can leave the reserve.

existing unstETH → factor
WETH payment     → seller
either both settle or neither does
Reference only

ERC-7540 / ERC-8161

An ERC-7540 request can be partly Pending and partly Claimable. The adapter transfers the Pending portion using ERC-8161 and redeems the Claimable portion to the factor before payment is allowed.

pending portion   → transferred
claimable portion → redeemed
complete value    → measured

Where the factor's money comes from

The factor's WETH is not left idle in a wallet. It lives in an Aave ERC-4626 vault, earning yield, and is withdrawn just in time inside the settlement transaction. Before a fill, idle balance can be zero. After a fill, only the exact payment has left and the remainder keeps earning.

What a fill takes out of the reserveBefore a fill the whole reserve is deposited in the Aave vault and the idle balance is zero. During a fill only the exact payment is withdrawn. After a fill the remainder is still deposited and still earning.BEFOREreserve depositedidle balance: zeroDURINGone fill settlesexact amount withdrawnAFTERfill completeremainder keeps earningreserve earning in Aave StataWETHstill earningpaymentreserve, less the payment
Because demand can be episodic, nothing sits in a wallet waiting: the reserve stays deposited, and a fill cuts out the exact payment and nothing more.

Market participant

The factor

The buyer with money now, willing to wait, charging for the wait.

01Holds capital

WETH in a productive funding account.

02Quotes prices

Signs offers offchain using its own risk policy.

03Stays offline

The seller sends the transaction, not the factor.

04Collects later

Redeems the claim when the queue finalizes.

Example pricing

Funding cost10% APR × 5 days≈ 0.0018 ETH
Risk margin0.15%≈ 0.0039 ETH
Collection gasEstimated≈ 0.003 ETH
Offer nowClaim value: 2.60 ETH~2.59 ETH

The discount pays for duration, impairment, protocol risk, opportunity cost, and operations. All of these risks transfer from the seller to the factor.

Why productive reserves matter

Factoring is episodic stress liquidity, so standby capital may wait between fills. Keeping the reserve in an ERC-4626 vault means the same capital earns lending yield while idle and can be materialized only when an accepted quote settles. Reported economic samples are preserved in the appendix, but their raw dataset is not reproduced in this repository.

Contracts

Architecture

Four contracts, one invariant.

Settlement kernelAsyncClaimSettlementPayment iff acquisition
CapitalProductiveFundingAccountERC-4626 vault · Aave WETH
ClaimProtocol adapterLido · ERC-7540 / ERC-8161

The kernel

AsyncClaimSettlement knows nothing about Lido, Aave, or a specific vault. It enforces a valid chain-bound signature, seller-only execution, fresh nonces and deadlines, exact funding, measurable claim acquisition before payment, and one settlement per quote.

The funding account

ProductiveFundingAccount materializes the exact payment from an ERC-4626 vault. If delivery is uncertain—the vault reverts, capacity is short, or the account is paused—it reports zero and settlement never starts.

The adapters

AdapterClaimAction
LidoWithdrawalClaimAdapterLido withdrawal ticketCreates a new request owned by the factor
ERC8161RedeemClaimAdapterERC-7540 redemption requestTransfers Pending and redeems Claimable portions

Adapters confirm acquisition by measuring balances before and after; they do not trust return values.

Where 1inch Aqua and SwapVM fit

Reservoir ships a working Aqua / SwapVM strategy: a custom VM instruction (0x92) clamps swap output to what the maker's ERC-4626 reserve can currently deliver, proven against production Aqua contracts on a mainnet fork. A factoring fill does not execute through SwapVM; it reuses the reserve engine built for that strategy to hold the factor's WETH in an Aave vault and withdraw the exact payment inside the fill.

The split is structural. A claim is not an ERC-20 and cannot be named in a SwapVM order, so claim settlement needs the kernel and its adapters. Aqua fits on the factor side: competing factors are makers whose capital must earn between fills, which is what the reserve engine provides.

Greendeterministic and mainnet-fork gatesUnit · integration · invariant · canonical protocol forks

Scope

Limits

Measured performance, unbuilt features, and where risk sits.

For liquid assets, use an exchange

An externally produced sample suggested that attractive factoring opportunities are clustered rather than continuous. The raw dataset and analysis pipeline are not in this repository, so the product does not present those reported figures as reproduced evidence.

Factoring applies when there is no liquid token market: a non-transferable claim, a position too large to sell without slippage, or stressed conditions where a factor is willing to accept queue timing and impairment risk.

What is not built

  • No competing factors yet.One factor, one funding account, one payment asset.
  • No secondary market.The factor holds each purchased claim to maturity.
  • No production ERC-8161 vault.The reference path is conformant; the Lido path runs against mainnet contracts.
  • Request ID zero is rejected.Ambiguous aggregate requests are refused rather than guessed.

Risk remains with the factor

The queue may take longer than modelled, the claim may settle below face value, withdrawals may pause, and capital may remain locked. There is no oracle, insurance, or pooled backstop. Each claim stands alone, so one impaired position cannot reach another.