The contract’s interface is on chain. To generate bindings or a Rust client, fetch the WASM:
Entrypoints
swap_exact_in
user.require_auth(). The aggregator then pullsamount_inoftoken_infromuserwithtransfer.- The fee is taken from the input and sent to the treasury (see Fees).
- Each route runs its hops in order, with the aggregator as the caller of every venue. Each hop’s output becomes the next hop’s input.
- The aggregator compares its own
token_outbalance before and after the routes. That difference is whatuserreceives, and it must be at leastmin_out, or the whole transaction reverts withInsufficientOutput.
Σ routes[i].amount_in == amount_in - fee. If they do not, the call fails with BadRoute.
swap_exact_out
amount_in values may not exceed max_in.
The fee is charged on the input the routes actually consumed.
user receives everything delivered (at least amount_out), and any unspent input is refunded.
There is no separate recipient: both entrypoints pay user.
Types
BadRoute):
- Every route has at least one hop and
amount_in > 0. - The first hop consumes
token_in, each hop consumes what the previous one produced, and the last hop producestoken_out. - Exact-in: the route amounts add up to exactly
amount_in - fee. Exact-out: they add up to at mostmax_in.
Fees
Every swap pays either the protocol fee or a partner fee, never both.partner = None: the rate isprotocol_bps, which is 10 bps today. Read it fromconfig().partner = Some(Partner { id, bps }): the rate isbps. It must sit betweenmin_partner_bps(25 today) and 1,000.idis at most 9 characters. The fee is booked toidin the treasury.fee = floor(amount_in * bps / 10000). A fee that rounds to zero is zero.
id and books the fee under it. That fee is only paid out to you if the id is the partner id Soroswap assigned you. API partners read their id and rate from GET /partner. If you call the contract without the API and want a partner fee, ask the Soroswap team for your partner id first.
When a quote was priced with a partner rate, the on-chain call has to pass the same Partner, or the route amounts will not add up.
Authorization
user authorizes swap_exact_in (or swap_exact_out) and, below it, the transfer of token_in from user to the aggregator.
useris an account (G…): simulation records both entries in one authorization tree, and the user signs it as usual.useris your contract: your contract’s direct call to the aggregator is authorized implicitly, but the tokentransferone level below is not. Authorize it withenv.authorize_as_current_contractright before the call. See Cross-Contract Integration.
Errors
Codes 9, 10 and 12 are admin-only (
NoPendingAdmin, BpsOutOfRange, NotInitialized).
Events
Each swap emits oneswap event:
- Topics:
["swap", token_in, token_out, user]. - Data:
{ amount_in, amount_out, fee, partner: Option<Symbol> }.
amount_in is the consumed input plus the fee.