Skip to content

About

Soroban settlement contract: obligations accrue, only net positions move, settlement cannot fail.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

SetOff

Soroban contracts for netted settlement on Stellar. Obligations accrue all window, only net positions move, and settlement cannot fail.

CI License


Anchors, payment providers and agent platforms on Stellar owe each other all day. Settling every obligation gross means each of them pre-funds its entire outflow. The settlement contract settles net: members record what they owe during a window, and at settlement each member's balance moves by its net position only. No tokens move between members at all.

The safety rule: after every batch of obligations, each debtor's net debit must be covered by its deposited balance. Members can owe far more than they hold, as long as it nets out, and settle can never fail for lack of funds.

Deployed on testnet

Contract CCW6QCOS…EYQV, using native XLM as the settlement token. scripts/testnet-demo.sh deploys a fresh copy and replays this:

Step Transaction
Allow native XLM 9060d30a…986b
Admit A, B and C in one call 72deba3c…6dc2
Refuse obligations below 1 XLM 5a16a3d1…d36e
A deposits 10 XLM collateral f39fb170…8a53
A owes B 10 XLM 00bcc214…420e
B owes C 10 XLM with no collateral: B is already owed 10 this window 14746e26…e6cd
C owes A 10 XLM 555239b8…5297
Settle: 30 XLM gross, every position 0, nothing moves 21925e89…b89c
A takes its collateral back with withdraw_all 9d335065…dac9

Testnet is reset every few months, after which these links stop resolving; the script reproduces the whole run on a fresh network.

Interface

Function Who What
__constructor(admin) deployer Sets the operator; windows may stay open 7 days before anyone can settle them
admit(member), admit_many(members) operator Admits members (up to 32 at once, all or none)
deposit(member, token, amount) member Moves collateral into the contract
withdraw(member, token, amount), withdraw_all(member, token) member Returns collateral not committed to the open window
submit(obligations) every debtor in the batch Records up to 32 obligations atomically; rejects the batch if any debtor's net debit is uncovered
settle() operator, or anyone once the window is overdue Applies every net position to balances and opens the next window
set_token, set_min_amount, set_max_window, set_position_quota, set_suspended, pause, unpause operator Operational controls; none can trap funds
propose_admin, accept_admin operator, then successor Two-step handover
extend_ttl(member, token) anyone Keeps a quiet member's entries from expiring
balance, position, available, open_positions, gross, window, window_timing, is_member, is_suspended, token_allowed, min_amount, position_quota, reference_used, paused, admin anyone Views

Every state change publishes an event (Admitted, Deposited, Withdrawn, Obligated, PositionSettled per member and token, Settled, and one per operator action), so members can reconcile from events alone. The contract's metadata names this repository, and releases publish the WASM with its SHA-256 for comparison with stellar contract fetch. TypeScript bindings come from stellar contract bindings typescript; CI checks they compile. Settlement receipts can be proven to third parties with Externalize.

Guarantees

  • Settlement cannot fail. After every batch, each member's net debit is covered by its balance; settle only moves numbers between balances.
  • Funds are never trapped. Pausing, suspending a member or disallowing a token stops new risk only: available balances can always be withdrawn, and any window left open past its bound (1 minute to 30 days, never unset) can be settled by anyone.
  • It fits in one transaction. A window holds at most 64 (member, token) positions and a batch at most 32 obligations; one member's obligations may open at most 16 of those positions per window (position_quota), so no single member can lock others out. Measured against testnet's limits, the largest settle uses 132 of 200 ledger writes and a full batch 11 of 16 KB of events; a test fails if either passes 75%.
  • Immutable. There is no upgrade function: the operator cannot replace the code holding members' collateral.

Build and test

cargo test                 # unit, randomised-invariant and resource-limit tests
stellar contract build     # target/wasm32v1-none/release/setoff_settlement.wasm, about 23 KB
NETWORK=testnet scripts/testnet-demo.sh

The invariant test drives random deposits, batches, withdrawals, settlements, pauses, suspensions and minimums, and checks after every step that tokens held equal balances, positions sum to zero, every net debit is covered, and rejected calls change nothing.

Related

  • setoff-engine: the off-chain netting algorithm and its reference vectors.
  • setoff-clearing: the clearing service; setoff soroban turns a closed window into calls on this contract.

Status

Not audited. See SECURITY.md.

License

Apache-2.0

About

Soroban settlement contract: obligations accrue, only net positions move, settlement cannot fail.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages