Skip to content
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
306f91f
Check order limit price
fedgiac Jul 23, 2026
6ceba6a
Check order amounts
fedgiac Jul 23, 2026
be30897
Clarify where the limit price validation comes from
fedgiac Jul 28, 2026
a205926
Clarify how pushes are split
fedgiac Jul 28, 2026
ebb6532
Consistently use .into() for instructions
fedgiac Jul 28, 2026
40b93d6
Have parsing iterator directly decode u64
fedgiac Jul 28, 2026
5d045ff
Sweep all options in locality test
fedgiac Jul 28, 2026
26af609
Merge branch 'main' into limit-price-check
fedgiac Jul 28, 2026
82f2684
Fix merge
fedgiac Jul 28, 2026
5a76fd9
Merge branch 'limit-price-check' into amounts-check
fedgiac Jul 28, 2026
ae32173
Condense destructuring
fedgiac Jul 28, 2026
10bb036
Collect to aray in test
fedgiac Jul 28, 2026
cbcd5ca
Collect to array in test, again
fedgiac Jul 28, 2026
9503b18
More efficient order in `if`
fedgiac Jul 28, 2026
5dcfde4
Skip unnecessary validation in edge case
fedgiac Jul 28, 2026
db36907
Simplify comments
fedgiac Jul 28, 2026
ac83628
impl TryFrom<&[u8]> for OrderAccount
fedgiac Jul 28, 2026
04ec557
Typo
fedgiac Jul 28, 2026
c3f3719
Fix spec drifting in the design document
fedgiac Jul 29, 2026
05eb465
Merge branch 'main' into limit-price-check
fedgiac Jul 29, 2026
cf18dba
Merge branch 'limit-price-check' into amounts-check
fedgiac Jul 29, 2026
535a940
Merge branch 'main' into limit-price-check
fedgiac Jul 30, 2026
3a7c2db
Merge branch 'limit-price-check' into amounts-check
kaze-cow Jul 30, 2026
23067ac
Merge branch 'main' into limit-price-check
fedgiac Jul 31, 2026
d5e3fdb
Merge branch 'limit-price-check' into amounts-check
fedgiac Jul 31, 2026
d2d8a80
Merge branch 'main' into amounts-check
fedgiac Jul 31, 2026
1ee96cb
Use simplified decoding mechanism in settle CLI
fedgiac Jul 31, 2026
fe86c69
Define IntentSpec
fedgiac Aug 3, 2026
7dfc653
Merge branch 'main' into amounts-check
fedgiac Aug 4, 2026
887efb2
Merge branch 'amounts-check' into fix-spec-drift
fedgiac Aug 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ It uses a dedicated state account to:

Its state is stored in a PDA generated using seed `["settlement"]`.

Once deployed, we will make the code at that account unchangeable.
Once the testing phase has ended, we will make the code at that account unchangeable.

## Buffer accounts

Buffer accounts are token accounts that hold funds on behalf of the settlement contract.

These token accounts are accessible to all solvers and effectively work like the current buffers. They are used to collect user funds, send out funds to the user, and collect fees, which stay on the buffers after the settlement. This means that the current fee accounting and withdrawal mechanism would be based on balance changes (like on Ethereum).
These token accounts are accessible to all solvers and effectively work like the current buffers. They are used to send out funds to the user and collect fees, which stay on the buffers after the settlement. This means that the current fee accounting and withdrawal mechanism would be based on balance changes (like on Ethereum).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm: buffer accounts are still used to Pull funds from users, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really: BeginSettle allows solvers to specify where to send the funds. This could be any arbitrary account, and so they don't need to even specify the sell token buffer account in the list of accounts. But if a solver wants, then the buffers can be used, so if they need it for some reason they can work with it.


Corresponding PDAs are generated using seed `["settlement", token, "buffer"]`.

Differences with Ethereum:

- In a settlement, a solver can only access buffers for tokens that are part of some order.
- In a settlement, a solver can't access buffers directly but needs to invoke a dedicated instruction or use the funds in them to pay out the proceeds of an order.
- Traded funds aren't sent automatically to the buffers at the start of the trade. Solvers can specify arbitrary receiver accounts for the user's sell tokens, as well as send the trade proceeds from any arbitrary account. In practice, buffers may still be used by solvers for pooling funds before interactions for efficiency reasons.

## Solver authentication
Expand Down Expand Up @@ -60,7 +60,7 @@ Withdrawing is triggered by the `CollectFromBuffer` instruction.
Differences with Ethereum:

- We don’t want to let the settlement program create orders for itself because, unlike in the EVM, it requires a specific code branch for that. This means that we can't follow the same withdraw mechanism we use right now. Pragmatically, at the start we should use the solver to withdraw the funds to a dedicated "dump" account and create orders to swap all funds to the same token (SOL). We don't plan to improve on this on the current iteration of the program.
- Withdrawing fees is done outside of a settlement.
- Withdrawing fees may be done outside of a settlement.

## User delegation (i.e., "approvals")

Expand Down Expand Up @@ -168,7 +168,7 @@ Note that deleting the order PDA is _not_ enough to invalidate an order. In fact

Allocating an order PDA requires paying rent.

If the order is expired, anyone can close the order account. On account closure, the rent is sent to the original creator of the order.
If the order is expired, anyone can close the order account through the `ReclaimOrder` instruction. On account closure, the rent is sent to the order's `created_by` account, i.e., the original creator of the order.

This is useful for solvers who need to allocate the order for executing it, but the allocation itself would be orders of magnitude more expensive than the compute cost for executing an instruction. This is particularly relevant to make small orders economically viable.

Expand Down Expand Up @@ -206,7 +206,7 @@ Differences with Ethereum:

Orders can be created by the owner by executing an instruction on-chain.

The order owner executes the `OwnerCreateOrderIntent` instruction. The settlement program checks that the order comes from the owner and [creates the order PDA](#orders-are-accounts).
The order owner executes the `CreateOrder` instruction. The settlement program checks that the order comes from the owner and [creates the order PDA](#orders-are-accounts).

In this authentication flow, the user needs to pay for the rent in SOL necessary to create the PDA. Note that the rent may be significantly higher than the expected trading fee. The rent can be recovered by the user once the order has expired by [clearing the order](#order-clearing).

Expand Down Expand Up @@ -259,7 +259,7 @@ A settlement transaction is split into multiple instructions. All settlement ope
- (arbitrary interactions): Any instruction from the solver. This could be a token transfer, an AMM swap, or anything else.
- `FinalizeSettle`: Pushes the proceeds of each order from the settlement’s buffer accounts to the order’s buy token account, using the settlement state PDA’s authority over the buffers. Carries an explicit `begin_ix_index` pointing to its paired `BeginSettle`.

Additionally, a settlement transaction will include the batch number as part of the instruction bytes of `BeginSettle`.
Additionally, `BeginSettle` includes the `auction_id` (an `i64`) as part of its instruction data. This value is unused by the program and only relied upon by the off-chain back-end services.

Only a single settlement can be executed at a time. This means that there can’t be a `BeginSettle` instruction or a spurious `FinalizeSettle` instruction between a coupled pair of `Begin`/`FinalizeSettle`.

Expand Down