Search Apps Documentation Source Content File Folder Download Copy Actions Download

factory_param.gno

3.16 Kb · 126 lines
  1package v1
  2
  3import (
  4	"strings"
  5
  6	u256 "gno.land/p/gnoswap/uint256"
  7	ufmt "gno.land/p/nt/ufmt/v0"
  8	"gno.land/r/gnoswap/pool"
  9)
 10
 11var Q192 = u256.Zero().Lsh(u256.One(), 192)
 12
 13var (
 14	minSqrtRatio = u256.MustFromDecimal(MIN_SQRT_RATIO)
 15	maxSqrtRatio = u256.MustFromDecimal(MAX_SQRT_RATIO)
 16)
 17
 18const (
 19	FeeTier100   uint32 = 100
 20	FeeTier500   uint32 = 500
 21	FeeTier3000  uint32 = 3000
 22	FeeTier10000 uint32 = 10000
 23)
 24
 25const (
 26	MIN_SQRT_RATIO string = "4295128739"
 27	MAX_SQRT_RATIO string = "1461446703485210103287273052203988822378723970342"
 28)
 29
 30// poolCreateConfig holds the essential parameters for creating a new pool.
 31type poolCreateConfig struct {
 32	token0Path       string
 33	token1Path       string
 34	fee              uint32
 35	sqrtPriceX96     *u256.Uint
 36	tickSpacing      int32
 37	slot0FeeProtocol uint8
 38}
 39
 40// newPoolParams defines the essential parameters for creating a new pool.
 41func newPoolParams(
 42	token0Path string,
 43	token1Path string,
 44	fee uint32,
 45	sqrtPriceX96 string,
 46	tickSpacing int32,
 47	slot0FeeProtocol uint8,
 48) *poolCreateConfig {
 49	price := u256.MustFromDecimal(sqrtPriceX96)
 50	return &poolCreateConfig{
 51		token0Path:       token0Path,
 52		token1Path:       token1Path,
 53		fee:              fee,
 54		sqrtPriceX96:     price,
 55		tickSpacing:      tickSpacing,
 56		slot0FeeProtocol: slot0FeeProtocol,
 57	}
 58}
 59
 60func (p *poolCreateConfig) SqrtPriceX96() *u256.Uint { return p.sqrtPriceX96 }
 61func (p *poolCreateConfig) TickSpacing() int32       { return p.tickSpacing }
 62func (p *poolCreateConfig) Token0Path() string       { return p.token0Path }
 63func (p *poolCreateConfig) Token1Path() string       { return p.token1Path }
 64func (p *poolCreateConfig) Fee() uint32              { return p.fee }
 65
 66func (p *poolCreateConfig) update() error {
 67	token0Path := p.token0Path
 68	token1Path := p.token1Path
 69
 70	// Always validate that the price is within valid range
 71	if err := validateSqrtPriceX96(p.sqrtPriceX96); err != nil {
 72		return err
 73	}
 74
 75	if !p.isInOrder() {
 76		token0Path, token1Path = token1Path, token0Path
 77
 78		// newPrice = 2^192 / oldPrice
 79		newPrice := u256.Zero().Div(Q192, p.sqrtPriceX96)
 80
 81		// Check if calculated price is within valid range
 82		if err := validateSqrtPriceX96(newPrice); err != nil {
 83			return err
 84		}
 85
 86		p.sqrtPriceX96 = newPrice
 87	}
 88
 89	p.token0Path = token0Path
 90	p.token1Path = token1Path
 91
 92	return nil
 93}
 94
 95// isInOrder checks if token paths are in lexicographical (or, alphabetical) order
 96func (p *poolCreateConfig) isInOrder() bool {
 97	if strings.Compare(p.token0Path, p.token1Path) < 0 {
 98		return true
 99	}
100	return false
101}
102
103func (p *poolCreateConfig) poolPath() string {
104	return pool.GetPoolPath(p.token0Path, p.token1Path, p.fee)
105}
106
107// validateSqrtPriceX96 validates that the given sqrtPriceX96 is within valid range
108func validateSqrtPriceX96(sqrtPriceX96 *u256.Uint) error {
109	// Valid range is [minSqrtRatio, maxSqrtRatio) - same as TickMathGetTickAtSqrtRatio
110	if sqrtPriceX96.Lt(minSqrtRatio) || sqrtPriceX96.Gte(maxSqrtRatio) {
111		return makeErrorWithDetails(
112			errOutOfRange,
113			ufmt.Sprintf("sqrtPriceX96(%s) is out of range", sqrtPriceX96.ToString()),
114		)
115	}
116	return nil
117}
118
119func isValidFeeTier(feeTier uint32) bool {
120	switch feeTier {
121	case FeeTier100, FeeTier500, FeeTier3000, FeeTier10000:
122		return true
123	}
124
125	return false
126}