Skip to content

Latest commit

 

History

History
117 lines (86 loc) · 4.51 KB

File metadata and controls

117 lines (86 loc) · 4.51 KB

Scale — measured on Monad testnet

Every number here came off chain 2026-08-09. Nothing is extrapolated from a local Foundry gas report, and nothing is an estimate. Reproduce with:

cd relayer && npx tsx src/loadTest.ts --plan     # price it, send nothing
cd relayer && npx tsx src/loadTest.ts            # run the book
cd relayer && npx tsx src/loadTest.ts --burst=12 # concurrency

Raw output, including every transaction hash: load-report.json.

What one trade costs

A complete factoring lifecycle is six transactions signed by three different parties.

Leg Signer Gas
confirmObligation obligor 346,414
originate supplier 564,780
approve (advance) financier 71,677
fund financier 731,057
approve (face) obligor 71,665
settle obligor 552,142
Total 2,337,735

At the 102 gwei observed, that is 0.238 MON per completed trade.

fund is the expensive leg, and the reason is the point of the project rather than an inefficiency: it moves real Cleanverse cvaUSD, and that transfer runs the A-Token's own compliance checks on both parties before any value moves. A stablecoin with no transfer-time verification would be cheaper and would not be enforcing anything.

The cost does not move with the invoice. The book below spans 5,600 to 156,000 cvaUSD and every trade in it costs the same gas — face value is one uint256 written once. Factoring economics are a percentage of face, so the margin on a Covenant trade improves as the invoice grows, and the floor at which a trade is worth doing at all is set by 0.238 MON, not by a percentage.

What the chain does with them

Monad testnet's block gas limit is 150,000,000. Divided by a full lifecycle:

~64 complete factoring lifecycles fit in a single block.

That is the useful capacity number, and it is the one an integrator should plan against — not a transactions-per-second figure that counts approvals.

Measured latency, submit to receipt, across the six legs of one trade:

p50 246 ms
p95 249 ms
max 249 ms

Under concurrency

Sequentially the client clears about 35 trades/minute, but that is a property of this script — it waits for each receipt before sending the next — and says nothing about the chain. So the same wallet signed ten confirmations up front with consecutive nonces and fired them without waiting:

submitted 10 transactions in 117 ms
mined in one block — 52,235,358
failures 0
all mined within 1.30 s of the first send

Nothing serialised, nothing was dropped, and no nonce gapped. All ten transaction hashes are in load-report.json under burst, each independently checkable against the chain.

The wall-clock figure is block cadence, not contention: the transactions were accepted in 117 ms and then waited together for the next block.

The register, as the book grows

The desk's instrument register reads every note through one Multicall3 batch of 50 rather than one getNote per token:

27 notes, 2 RPC round trips, 97 ms.

Read cost is a function of ceil(notes / 50), not of note count, so the desk's load time is flat until the book passes fifty and then steps once. Before this change the register issued one request per note and stopped at a hard ceiling of 200.

The book these numbers came from

The measurements are not synthetic traffic. They are a real book of varied trades run end to end against the deployed contracts with the four live demo wallets:

notes on chain 27
distinct face values 16
distinct maturities 9
settled / funded / open 16 / 6 / 5
total face value 2,018,230 cvaUSD

Two advance rates appear because the two live obligors sit in different bands — subTier 90 prices at 9,700 bps and subTier 30 at 8,800 bps, exactly the curve the desk publishes.

What this does not measure

Stated so the numbers above are not read as more than they are:

  • One RPC endpoint, one client. This measures the chain and the contracts, not a production deployment's own throughput ceiling.
  • Testnet. Monad mainnet's fee market will differ; the gas figures will not.
  • Twelve concurrent transactions, not twelve thousand. It establishes that the lifecycle does not serialise. It does not establish a saturation point.
  • The relayer is not in the hot path. A-Pass mirroring happens out of band, so its cost is not part of a trade and is not counted here.