Search Apps Documentation Source Content File Folder Download Copy Actions Download

factory_param.gno

3.71 Kb ยท 152 lines
  1package v1
  2
  3import (
  4	"strings"
  5
  6	u256 "gno.land/p/gnoswap/uint256"
  7	"gno.land/p/nt/ufmt"
  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	GNOT_DENOM  string = "ugnot"
 27	WUGNOT_PATH string = "gno.land/r/gnoland/wugnot"
 28)
 29
 30const (
 31	MIN_SQRT_RATIO string = "4295128739"
 32	MAX_SQRT_RATIO string = "1461446703485210103287273052203988822378723970342"
 33)
 34
 35// poolCreateConfig holds the essential parameters for creating a new pool.
 36type poolCreateConfig struct {
 37	token0Path       string
 38	token1Path       string
 39	fee              uint32
 40	sqrtPriceX96     *u256.Uint
 41	tickSpacing      int32
 42	slot0FeeProtocol uint8
 43}
 44
 45// newPoolParams defines the essential parameters for creating a new pool.
 46func newPoolParams(
 47	token0Path string,
 48	token1Path string,
 49	fee uint32,
 50	sqrtPriceX96 string,
 51	tickSpacing int32,
 52	slot0FeeProtocol uint8,
 53) *poolCreateConfig {
 54	price := u256.MustFromDecimal(sqrtPriceX96)
 55	return &poolCreateConfig{
 56		token0Path:       token0Path,
 57		token1Path:       token1Path,
 58		fee:              fee,
 59		sqrtPriceX96:     price,
 60		tickSpacing:      tickSpacing,
 61		slot0FeeProtocol: slot0FeeProtocol,
 62	}
 63}
 64
 65func (p *poolCreateConfig) SqrtPriceX96() *u256.Uint { return p.sqrtPriceX96 }
 66func (p *poolCreateConfig) TickSpacing() int32       { return p.tickSpacing }
 67func (p *poolCreateConfig) Token0Path() string       { return p.token0Path }
 68func (p *poolCreateConfig) Token1Path() string       { return p.token1Path }
 69func (p *poolCreateConfig) Fee() uint32              { return p.fee }
 70
 71func (p *poolCreateConfig) updateWithWrapping() error {
 72	token0Path, token1Path := p.wrap()
 73
 74	// Always validate that the price is within valid range
 75	if err := validateSqrtPriceX96(p.sqrtPriceX96); err != nil {
 76		return err
 77	}
 78
 79	if !p.isInOrder() {
 80		token0Path, token1Path = token1Path, token0Path
 81
 82		// newPrice = 2^192 / oldPrice
 83		newPrice := u256.Zero().Div(Q192, p.sqrtPriceX96)
 84
 85		// Check if calculated price is within valid range
 86		if err := validateSqrtPriceX96(newPrice); err != nil {
 87			return err
 88		}
 89
 90		p.sqrtPriceX96 = newPrice
 91	}
 92
 93	p.token0Path = token0Path
 94	p.token1Path = token1Path
 95
 96	return nil
 97}
 98
 99func (p *poolCreateConfig) isSameTokenPath() bool {
100	return p.token0Path == p.token1Path
101}
102
103// isInOrder checks if token paths are in lexicographical (or, alphabetical) order
104func (p *poolCreateConfig) isInOrder() bool {
105	if strings.Compare(p.token0Path, p.token1Path) < 0 {
106		return true
107	}
108	return false
109}
110
111func (p *poolCreateConfig) wrap() (string, string) {
112	if p.token0Path == GNOT_DENOM {
113		p.token0Path = WUGNOT_PATH
114	}
115	if p.token1Path == GNOT_DENOM {
116		p.token1Path = WUGNOT_PATH
117	}
118	return p.token0Path, p.token1Path
119}
120
121func (p *poolCreateConfig) poolPath() string {
122	return pool.GetPoolPath(p.token0Path, p.token1Path, p.fee)
123}
124
125func (p *poolCreateConfig) isSupportedFee(feeTier uint32) bool {
126	switch feeTier {
127	case FeeTier100, FeeTier500, FeeTier3000, FeeTier10000:
128		return true
129	}
130	return false
131}
132
133// validateSqrtPriceX96 validates that the given sqrtPriceX96 is within valid range
134func validateSqrtPriceX96(sqrtPriceX96 *u256.Uint) error {
135	// Valid range is [minSqrtRatio, maxSqrtRatio) - same as TickMathGetTickAtSqrtRatio
136	if sqrtPriceX96.Lt(minSqrtRatio) || sqrtPriceX96.Gte(maxSqrtRatio) {
137		return makeErrorWithDetails(
138			errOutOfRange,
139			ufmt.Sprintf("sqrtPriceX96(%s) is out of range", sqrtPriceX96.ToString()),
140		)
141	}
142	return nil
143}
144
145func isValidFeeTier(feeTier uint32) bool {
146	switch feeTier {
147	case FeeTier100, FeeTier500, FeeTier3000, FeeTier10000:
148		return true
149	}
150
151	return false
152}