Execute a strategy
swap_xdr as a StrategyPayload, pulls total_in
from sender, and credits the measured receipt. It applies any input fee,
executes swaps and LP operations in their encoded order, applies any output
fee, checks minimum output, and pays sender. Remaining token balances are
settled as residual revenue before it returns the output amount.
Anyone may call it. sender authorizes the pull.
A payload that fails to decode raises #13 InvalidRouteXdr.
Strategy payload
swap_xdr decodes from ScVal XDR into two registries and a packed program:
u8 index. Each instruction occupies
five bytes. The ops stream begins with this ten-byte header:
Split weights are
u24 big-endian parts per million, each in 1..=1_000_000.
Each weight applies to the input token’s remaining balance at that instruction;
the weights have no sum requirement. A 50/50 split uses 500_000, then All
to spend the remainder, including rounding dust.
Use the quote service to produce these bytes. The wire layout is reference
material. The current wire version is 1. A program permits at most 48
instructions, 32 split weights, 256 assets, and 126 amounts. The packed stream
length is 10 + 5 * instruction_count + 3 * split_weight_count bytes.
Use the SDK’s public decodeStellarRouteBytes to inspect a route and
verifyStellarRouteBytes to check your expected pair, input amount, and minimum
output. Use mapQuoteResponseToStrategySwap when you have the quote response.
Pass caller-owned values in expected; checking response fields alone does
not prove the trade matches your request. Integrations forward the verified
payload bytes without rebuilding the program.
Fees
Each configured fee is capped atFEE_CAP = 1000 basis points (10%).
When fees apply, their combined rate must also be at most 1000 bps.
Exceeding either limit raises #21 FeeTooHigh.
A payload carries a referral id in its header (
u32, where 0 means none).
Both fees require an active referral. A zero, unknown, or inactive referral
id charges neither the static fee nor the referral fee.
Static and referral fees each round down in token base units. Their rounded
amounts are added; the router does not round the combined rate once.
Fees use the input token unless only the output token is fee-whitelisted;
then they use the output token. The whitelist selects the fee side and does
not restrict which tokens can be swapped. Fees accrue into per-token buckets
and are claimed separately.
After payout, residual balances accrue to the admin bucket independently of
referral fees. Each token’s residual must be at most
max(1000, floor(credited_amount / 1_000_000)) native units, or execution
reverts with #29 ExcessiveResidual. The router retains permitted residuals
as admin revenue; it does not refund unused input to the sender. The lending
controller can refund input that the router never pulled, which is a separate
balance check.
Claiming fees
Owner-only administration
The contract owner authorizes these calls.
Transfer ownership in two steps: call
transfer_ownership(new_owner, live_until_ledger), then have the incoming owner call accept_ownership().
get_owner() returns None when no owner is set. The router exposes no
renounce_ownership entrypoint.
Open reads
Error codes
Match these codes within the swap aggregator’s error domain. The lending contracts use a separate enum.Next
Strategies
How controller strategies authorize swaps and settle balance changes.
Stellar Aggregator
The quote service that builds the route bytes.
Security model
Why the controller treats this contract as untrusted.
Addresses
Swap-aggregator registry addresses and verification steps.

