Skip to main content
Technical reference for the Stableswapper swap instruction. For setup and examples, see Quickstart or Examples.

Swap Function

Contract: 0x57AB1E2c6289aCe985Bd5c5571EbF6d98CD41Ab7 (Key Addresses)

Function Signature

function swap(
    address tokenIn,
    address tokenOut,
    uint256 amountIn,
    uint256 minAmountOut,
    address recipient
) external

Parameters

ParameterTypeDescription
tokenInaddressAddress of the ERC-20 token being swapped from
tokenOutaddressAddress of the ERC-20 token being swapped to
amountInuint256Amount of input token to swap (in token’s native decimals, before fees)
minAmountOutuint256Minimum acceptable output amount (slippage protection)
recipientaddressAddress that receives the output tokens

Preconditions

  • The caller must have approved the Stableswapper contract to spend at least amountIn of tokenIn (ERC-20 approve)
  • Both tokenIn and tokenOut must be listed and swappable
  • The SWAP feature flag must be enabled
  • If the ALLOWLIST feature is enabled, msg.sender must be allowlisted
  • amountIn and minAmountOut must be greater than zero
  • tokenIn and tokenOut must be different addresses
  • recipient must not be the zero address

Fee Model

Fees are charged on the input token and deducted before the 1:1 swap calculation.
StepDescription
1Full amountIn is transferred from the caller to the contract
2Fee is calculated: fee = ceil(amountIn * feeBasisPoints / 10000)
3Fee is transferred from the contract to the feeRecipient
4Net amount (amountIn - fee) is normalized for decimal differences and sent to recipient
Example: Swapping 100 USDC with a 1% fee (100 basis points):
  • User sends: 100 USDC
  • Fee: 1 USDC (sent to fee recipient)
  • User receives: 99 of the output token (normalized for decimals)

View Functions

Token State

FunctionReturnsDescription
isTokenListed(address token)boolWhether a token is listed on the contract
isTokenSwappable(address token)boolWhether a listed token is currently enabled for swapping
getTokenDecimals(address token)uint8Cached decimals for a listed token
getListedTokens()address[]Array of all listed token addresses
getListedTokensCount()uint256Number of listed tokens
getReservedAmount(address token)uint256Amount reserved (not available for swaps)

Fee Configuration

FunctionReturnsDescription
feeBasisPoints()uint16Current fee in basis points (e.g., 100 = 1%)
feeRecipient()addressAddress that receives collected fees

Access Control

FunctionReturnsDescription
isAllowlisted(address addr)boolWhether an address is on the allowlist
isFeatureEnabled(FeatureFlag feature)boolWhether a feature flag is enabled
Feature flag values:
ValueFeatureDescription
0SWAPEnables/disables all swap operations
1WITHDRAWEnables/disables liquidity withdrawals
2ALLOWLISTWhen enabled, only allowlisted addresses can swap

Events

EventParametersDescription
Swapcaller, tokenIn, tokenOut, amountIn, amountOut, fee, recipientEmitted on every successful swap
TokenListingUpdatedtoken, isListedToken added or removed from listings
TokenStatusUpdatedtoken, isSwappableToken swapping enabled or disabled
FeeUpdatedoldFeeBasisPoints, newFeeBasisPointsFee rate changed
FeeRecipientUpdatedoldFeeRecipient, newFeeRecipientFee recipient address changed
FeatureFlagUpdatedfeature, isEnabledFeature flag toggled
AllowlistUpdatedaddr, isAllowlistedAddress added to or removed from allowlist

Error Reference

ErrorDescription
SwapsCannotBePaused()Swap feature is disabled
CannotBeZeroAddress()A required address parameter is the zero address
CannotSwapSameToken(token)tokenIn and tokenOut are the same
TokenNotListed(token)Token is not listed on the contract
CannotBeZeroAmount()amountIn or minAmountOut is zero
AddressNotInAllowlist(addr)Allowlist is enabled and caller is not allowlisted
TokenMustBeSwappable(token)Token is listed but not currently swappable
SlippageExceeded()Output amount is below minAmountOut
TokenOutBalanceLessThanReservedAmount(token)Contract balance is less than the reserved amount
AmountOutExceedsAvailableLiquidity(amountOut, availableLiquidity)Insufficient liquidity after accounting for reserves

Roles

The contract uses role-based access control. These roles are managed by the DEFAULT_ADMIN_ROLE holder.
RolePermissions
DEFAULT_ADMIN_ROLEAuthorize upgrades, grant/revoke all roles (single holder, 2-step transfer)
TREASURY_ROLEWithdraw liquidity, update reserved amounts
CONFIGURE_ROLEList/unlist tokens, update fees, manage allowlist
PAUSE_ROLEPause/unpause swaps and withdrawals, enable/disable individual tokens

Examples

Code samples for common swap scenarios

Quickstart

Get up and running in 10 minutes

Key Addresses

Program IDs and deployed addresses

Production Readiness

Helper functions and best practices