6.7 KiB
6.7 KiB
Slippage Mapping
This document describes how SlippageBps is derived for each supported swap protocol in this repository.
Unified Fields
Each parsed Swap may include these normalized fields:
SwapModeFixedAmountFixedAmountSideFixedMintLimitAmountTypeLimitAmountLimitAmountSideLimitMintActualLimitAmountActualLimitAmountSideSlippageBps
Internal Enum Mapping
These fields are stored internally as uint8 enums and serialized as strings in JSON / debug output.
SwapMode
| Raw Value | Name | Serialized Value |
|---|---|---|
0 |
SwapModeUnknown |
"" |
1 |
SwapModeExactIn |
"exact_in" |
2 |
SwapModeExactOut |
"exact_out" |
SwapAmountSide
Used by:
FixedAmountSideLimitAmountSideActualLimitAmountSide
| Raw Value | Name | Serialized Value |
|---|---|---|
0 |
SwapAmountSideUnknown |
"" |
1 |
SwapAmountSideBase |
"base" |
2 |
SwapAmountSideQuote |
"quote" |
SwapLimitType
Used by:
LimitAmountType
| Raw Value | Name | Serialized Value |
|---|---|---|
0 |
SwapLimitTypeUnknown |
"" |
1 |
SwapLimitTypeMinOut |
"min_out" |
2 |
SwapLimitTypeMaxIn |
"max_in" |
Calculation Rules
exact_inSlippageBps = (actual_out - min_out) / actual_out * 10000
exact_outSlippageBps = (max_in - actual_in) / max_in * 10000
Interpretation:
- Positive: execution is better than the user limit
- Zero: execution lands exactly on the user limit
10000: user limit is effectively unbounded on the constrained side (for examplemin_out = 0)- Negative raw headroom is clamped to
0because successful-swap storage uses a non-negative bounded metric
This definition makes SlippageBps a bounded "remaining headroom to the user's limit" metric for successful swaps:
exact_in: how much output headroom remained, measured against the realized outputexact_out: how much input headroom remained, measured against the allowed max input
Protocol Mapping
| Protocol | Method Semantics | SwapMode |
FixedAmount |
LimitAmountType |
LimitAmount |
ActualLimitAmount |
|---|---|---|---|---|---|---|
Pump |
buy |
exact_out |
target token amount | max_in |
max SOL in | actual SOL in |
Pump |
buy_exact_sol_in |
exact_in |
SOL in | min_out |
min token out | actual token out |
Pump |
sell |
exact_in |
token in | min_out |
min SOL out | actual SOL out |
PumpAMM |
buy |
exact_out |
target base out | max_in |
max quote in | actual quote in |
PumpAMM |
buy_exact_quote_in |
exact_in |
quote in | min_out |
min base out | actual base out |
PumpAMM |
sell |
exact_in |
base in | min_out |
min quote out | actual quote out |
MeteoraDLMM |
swap / swap2 / swap_with_price_impact |
exact_in |
AmountIn |
min_out |
instruction min out | event output |
MeteoraDLMM |
swap_exact_out / swap_exact_out2 |
exact_out |
OutAmount |
max_in |
MaxInAmount |
event input |
MeteoraPools |
swap |
exact_in |
InAmount |
min_out |
MinimumOutAmount |
actual output side |
MeteoraBondingCurve |
swap / swap2 |
exact_in |
AmountIn |
min_out |
MinimumAmountOut |
actual output side |
MeteoraAmmV2 |
swap / swap2 exact-in or partial |
exact_in |
params input side | min_out |
params output threshold | actual output side |
MeteoraAmmV2 |
swap / swap2 exact-out |
exact_out |
params target output | max_in |
params max input | actual input side |
RaydiumLaunchLab |
*_ExactIn |
exact_in |
Amount |
min_out |
OtherAmountThreshold |
actual output side |
RaydiumLaunchLab |
*_ExactOut |
exact_out |
Amount |
max_in |
OtherAmountThreshold |
actual input side |
RaydiumCPMM |
swap_base_input |
exact_in |
AmountIn |
min_out |
MinimumAmountOut |
actual output side |
RaydiumCPMM |
swap_base_output |
exact_out |
AmountOut |
max_in |
MaxAmountIn |
actual input side |
RaydiumCLMM |
swap / swap_v2 |
exact_in or exact_out |
amount |
min_out or max_in |
other_amount_threshold |
opposite-side actual amount |
RaydiumV4 |
swap_base_in / swap_base_in_v2 |
exact_in |
amount_in |
min_out |
minimum_amount_out |
actual output side |
RaydiumV4 |
swap_base_out / swap_base_out_v2 |
exact_out |
amount_out |
max_in |
max_amount_in |
actual input side |
OrcaWhirlpool |
swap / swap_v2 |
exact_in or exact_out |
amount |
min_out or max_in |
other_amount_threshold |
opposite-side actual amount |
OrcaWhirlpool |
two_hop_swap / two_hop_swap_v2 |
route-level | route specified amount | min_out or max_in |
route threshold | route final output or total input |
Notes
Pumpquote side is normalized towSOLin the slippage fields, even when legacySwap.QuoteMintis not populated.OrcaWhirlpooltwo-hop instructions use route-level slippage. The normalized slippage fields are attached to the first returned swap entry.MeteoraAmmV2usesSwapMode.ExactIn,SwapMode.PartialFill, andSwapMode.ExactOut.PartialFillis treated like exact-in for slippage purposes because it still uses a minimum-output threshold.
DAMM v2 Verification
The MeteoraAmmV2 mapping has been checked against the program IDL for cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG.
swap- instruction arg type:
SwapParameters - fields:
amountIn,minimumAmountOut - semantics: exact-in
- instruction arg type:
swap2:- instruction / event arg type:
SwapParameters2 amount0: "When it's exact in, partial fill, this will be amount_in. When it's exact out, this will be amount_out"amount1: "When it's exact in, partial fill, this will be minimum_amount_out. When it's exact out, this will be maximum_amount_in"swapMode:ExactIn,PartialFill,ExactOut
- instruction / event arg type:
The downloaded JSON IDL references SwapMode in the field docs but does not inline the enum body itself. In this repository, the raw swapMode values are interpreted consistently as:
0 = ExactIn1 = PartialFill2 = ExactOut
That means the parser mapping is:
swap2+ExactIn/PartialFillFixedAmount = amount0LimitAmount = amount1LimitAmountType = min_out
swap2+ExactOutFixedAmount = amount0LimitAmount = amount1LimitAmountType = max_in
Source Files
Swapnormalized fields:tx.go- Shared slippage mapping helpers:
swap_amounts.go - Protocol parsers:
pump.gopumpamm.gometaoradlmm.gometaorapool.gometeora_bonding_curve.gometeoradamm.goraydiumlaunchlab.goraydiumcpmm.goraydiumclmm.goraydiumv4.goorcawhirpool.go