Skip to main content
The swap aggregator is the on-chain router that executes swap routes. Controller strategies call it, and you can call it directly — it is not restricted to protocol use.
This page documents the contract. For the off-chain quote service that produces the route bytes — the HTTP API, token coverage, and prepared transaction envelopes — see Stellar Aggregator. You will normally use both: the service builds the payload, this contract executes it.
The lending protocol treats this contract as untrusted. The controller grants it authority for one stated input amount, ignores whatever it returns, and settles on measured balance deltas instead. It is also not owned by governance — it has its own owner and its own two-step ownership transfer.

The one entry point that matters

It decodes swap_xdr as a StrategyPayload, pulls total_in from sender, runs any LP burn, then the swap paths, then any LP mint, applies fees, enforces the minimum output, and returns the delivered amount. Anyone may call it. sender authorizes the pull. A payload that fails to decode raises #13 InvalidRouteXdr. The payload’s shape — two registries plus a packed instruction stream — is documented in Strategies.
Slippage is enforced here, not by the controller. Your minimum output lives inside the payload bytes, and execute_strategy is the only thing that checks it. Falling short raises #5 SlippageExceeded. Build that floor correctly in your quote — nothing downstream will catch a bad price for you.

Fees

Two fees can apply, both in basis points, both capped at FEE_CAP = 1000 (10%). Exceeding the cap raises #21 FeeTooHigh. A payload carries a referral id in its header (u32, where 0 means none). Fees accrue into per-token buckets and are claimed separately — they are not swept into the swap output.

Claiming fees

claim_referral_fees being permissionless is safe by construction: the recipient is read from stored referral config, so calling it on someone else’s behalf just pays them. You cannot redirect it.

Owner-only administration

All of these carry #[only_owner]. Ownership is the standard two-step: transfer_ownership(new_owner, live_until_ledger), then accept_ownership() by the incoming owner. get_owner() returns None if ownership was renounced or never set.

Open reads

Error codes

This contract uses its own error enum, unrelated to the lending protocol’s codes. A #5 here is not a #5 from the controller.

Next

Strategies

How controller strategies call this contract, and the payload layout.

Stellar Aggregator

The quote service that builds the route bytes.

Security model

Why the controller treats this contract as untrusted.

Addresses

Deployed swap-aggregator addresses per network.