package router import ( u256 "gno.land/p/gnoswap/uint256/v1" ufmt "gno.land/p/nt/ufmt/v0" ) const ( rawUnknown = "UNKNOWN" rawExactIn = "EXACT_IN" rawExactOut = "EXACT_OUT" zeroAddress = address("") ) type SwapType string const ( Unknown SwapType = rawUnknown // ExactIn represents a swap type where the input amount is exact and the output amount may vary. // Used when a user wants to swap a specific amount of input tokens. ExactIn SwapType = rawExactIn // ExactOut represents a swap type where the output amount is exact and the input amount may vary. // Used when a user wants to swap a specific amount of output tokens. ExactOut SwapType = rawExactOut ) // trySwapTypeFromStr attempts to convert a string into a SwapType. // It validates and converts string representations of swap types into their corresponding enum values. func trySwapTypeFromStr(swapType string) (SwapType, error) { switch swapType { case rawExactIn: return ExactIn, nil case rawExactOut: return ExactOut, nil default: return "", ufmt.Errorf("unknown swapType: expected ExactIn or ExactOut, got %s", swapType) } } // String returns the wire-format string for a SwapType. // // Returns: // - swapType: EXACT_IN or EXACT_OUT for known values, or an empty string for Unknown func (s SwapType) String() string { switch s { case ExactIn: return rawExactIn case ExactOut: return rawExactOut default: return "" } } // SingleSwapParams contains parameters for executing a single pool swap. // It represents the simplest form of swap that occurs within a single liquidity pool. type SingleSwapParams struct { tokenIn string // token to spend tokenOut string // token to receive fee uint32 // fee of the pool used to swap // Amount specified for the swap: // - Positive: exact input amount (tokenIn) // - Negative: exact output amount (tokenOut) amountSpecified int64 sqrtPriceLimitX96 *u256.Uint // sqrtPriceLimitX96 for the swap, empty string or zero string means no limit } // TokenIn returns the input token contract path. // // Returns: // - tokenIn: token spent by this single-pool swap func (p SingleSwapParams) TokenIn() string { return p.tokenIn } // TokenOut returns the output token contract path. // // Returns: // - tokenOut: token received by this single-pool swap func (p SingleSwapParams) TokenOut() string { return p.tokenOut } // Fee returns the pool fee tier. // // Returns: // - fee: fee tier encoded as the pool's uint32 fee value func (p SingleSwapParams) Fee() uint32 { return p.fee } // SqrtPriceLimitX96 returns the optional Q64.96 square-root price limit. // A nil stored limit is normalized to the zero value, which callers interpret as no explicit limit. // // Returns: // - limit: configured Q64.96 price limit, or a zero uint when no limit was supplied func (p SingleSwapParams) SqrtPriceLimitX96() *u256.Uint { if p.sqrtPriceLimitX96 == nil { return u256.Zero() } return p.sqrtPriceLimitX96 } // SwapParams contains parameters for executing a multi-hop swap operation. type SwapParams struct { SingleSwapParams recipient address // address to receive the token } // TokenIn returns the input token contract path. // // Returns: // - tokenIn: token spent by this multi-hop swap parameters object func (p SwapParams) TokenIn() string { return p.tokenIn } // TokenOut returns the output token contract path. // // Returns: // - tokenOut: token received by this multi-hop swap parameters object func (p SwapParams) TokenOut() string { return p.tokenOut } // Fee returns the pool fee tier. // // Returns: // - fee: fee tier encoded as the pool's uint32 fee value func (p SwapParams) Fee() uint32 { return p.fee } // Recipient returns the address that receives swap output. // // Returns: // - recipient: configured output recipient address func (p SwapParams) Recipient() address { return p.recipient } // newSwapParams creates a new SwapParams instance with the provided parameters. func newSwapParams(tokenIn, tokenOut string, fee uint32, recipient address, amountSpecified int64) *SwapParams { return &SwapParams{ SingleSwapParams: SingleSwapParams{ tokenIn: tokenIn, tokenOut: tokenOut, fee: fee, amountSpecified: amountSpecified, }, recipient: recipient, } } // SwapResult encapsulates the outcome of a swap operation. type SwapResult struct { Routes []string Quotes []string AmountIn int64 AmountOut int64 AmountSpecified int64 } // SwapParamsI defines the common interface for swap parameters. type SwapParamsI interface { // TokenIn returns the input token path required by swap processing. // // Returns: // - tokenIn: token spent by the swap TokenIn() string // TokenOut returns the output token path required by swap processing. // // Returns: // - tokenOut: token received by the swap TokenOut() string // Fee returns the pool fee tier required by swap processing. // // Returns: // - fee: pool fee tier Fee() uint32 } // SwapCallbackData contains the callback data required for swap execution. // This type is used to pass necessary information during the swap callback process, // ensuring proper token transfers and pool data updates. type SwapCallbackData struct { tokenIn string // token to spend tokenOut string // token to receive fee uint32 // fee of the pool used to swap payer address // address to spend the token } // newSwapCallbackData creates a new SwapCallbackData from a SwapParamsI. func newSwapCallbackData(params SwapParamsI, payer address) SwapCallbackData { return SwapCallbackData{ tokenIn: params.TokenIn(), tokenOut: params.TokenOut(), fee: params.Fee(), payer: payer, } } // newDrySwapCallbackData creates callback data for a dry swap. The payer is // deliberately the zero address because dry swaps do not execute callbacks or // token transfers. func newDrySwapCallbackData(params SwapParamsI) SwapCallbackData { return SwapCallbackData{ tokenIn: params.TokenIn(), tokenOut: params.TokenOut(), fee: params.Fee(), payer: zeroAddress, } } // ExactInParams contains parameters for exact input swaps. type ExactInParams struct { BaseSwapParams AmountIn int64 AmountOutMin int64 } // NewExactInParams creates parameters for an exact-input swap. // // Parameters: // - baseParams: shared token, route, quote, price-limit, and deadline settings // - amountIn: exact input amount in token units; must be positive before execution // - amountOutMin: minimum acceptable output amount in token units // // Returns: // - params: exact-input parameters combining baseParams and amount limits func NewExactInParams( baseParams BaseSwapParams, amountIn int64, amountOutMin int64, ) ExactInParams { return ExactInParams{ BaseSwapParams: baseParams, AmountIn: amountIn, AmountOutMin: amountOutMin, } } // ExactOutParams contains parameters for exact output swaps. type ExactOutParams struct { BaseSwapParams AmountOut int64 AmountInMax int64 } // NewExactOutParams creates parameters for an exact-output swap. // // Parameters: // - baseParams: shared token, route, quote, price-limit, and deadline settings // - amountOut: requested output amount in token units; must be positive before execution // - amountInMax: maximum acceptable input amount in token units // // Returns: // - params: exact-output parameters combining baseParams and amount limits func NewExactOutParams( baseParams BaseSwapParams, amountOut int64, amountInMax int64, ) ExactOutParams { return ExactOutParams{ BaseSwapParams: baseParams, AmountOut: amountOut, AmountInMax: amountInMax, } }