Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

utils.gno

3.92 Kb · 114 lines
  1package pool
  2
  3import (
  4	i256 "gno.land/p/gnoswap/int256/v1"
  5	u256 "gno.land/p/gnoswap/uint256/v1"
  6	ufmt "gno.land/p/nt/ufmt/v0"
  7)
  8
  9const (
 10	MAX_UINT64  string = "18446744073709551615"
 11	MAX_INT64   string = "9223372036854775807"
 12	MAX_INT128  string = "170141183460469231731687303715884105727"
 13	MIN_INT128  string = "-170141183460469231731687303715884105728"
 14	MAX_UINT128 string = "340282366920938463463374607431768211455"
 15	MAX_INT256  string = "57896044618658097711785492504343953926634992332820282019728792003956564819967"
 16
 17	INT64_MIN int64 = -9223372036854775808
 18	INT64_MAX int64 = 9223372036854775807
 19
 20	Q96_RESOLUTION  uint = 96
 21	Q128_RESOLUTION uint = 128
 22
 23	Q64  string = "18446744073709551616"                    // 2 ** 64
 24	Q96  string = "79228162514264337593543950336"           // 2 ** 96
 25	Q128 string = "340282366920938463463374607431768211456" // 2 ** 128
 26)
 27
 28var (
 29	maxInt128FromDecimal  = i256.MustFromDecimal(MAX_INT128)
 30	minInt128FromDecimal  = i256.MustFromDecimal(MIN_INT128)
 31	maxUint128FromDecimal = u256.MustFromDecimal(MAX_UINT128)
 32	q128FromDecimal       = u256.MustFromDecimal(Q128)
 33)
 34
 35var uint128Mask = func() *u256.Uint {
 36	m := u256.Zero().Lsh(u256.One(), Q128_RESOLUTION)
 37	return m.Sub(m, u256.One())
 38}()
 39
 40// toUint128 ensures a *u256.Uint value fits within the uint128 range.
 41//
 42// This function validates that the given `value` is properly initialized and checks whether
 43// it exceeds the maximum value of uint128. If the value exceeds the uint128 range,
 44// it applies a masking operation to truncate the value to fit within the uint128 limit.
 45//
 46// Parameters:
 47//   - value: *u256.Uint, the value to be checked and possibly truncated.
 48//
 49// Returns:
 50//   - *u256.Uint: A value guaranteed to fit within the uint128 range.
 51//
 52// Notes:
 53//   - The function first checks if the value is not nil to avoid potential runtime errors.
 54//   - The mask ensures that only the lower 128 bits of the value are retained.
 55//   - If the input value is already within the uint128 range, it is returned unchanged.
 56//   - If masking is required, a new instance is returned without modifying the input.
 57//   - MAX_UINT128 is a constant representing `2^128 - 1`.
 58func toUint128(value *u256.Uint) *u256.Uint {
 59	if value == nil {
 60		panic(newErrorWithDetail(errInvalidInput, "value is nil"))
 61	}
 62
 63	if value.Gt(maxUint128FromDecimal) {
 64		return u256.Zero().And(value, uint128Mask)
 65	}
 66	return value
 67}
 68
 69// u256Min returns the smaller of two *u256.Uint values.
 70//
 71// This function compares two unsigned 256-bit integers and returns the smaller of the two.
 72// If `num1` is less than `num2`, it returns `num1`; otherwise, it returns `num2`.
 73//
 74// Parameters:
 75// - num1 (*u256.Uint): The first unsigned 256-bit integer.
 76// - num2 (*u256.Uint): The second unsigned 256-bit integer.
 77//
 78// Returns:
 79// - *u256.Uint: The smaller of `num1` and `num2`.
 80//
 81// Notes:
 82//   - This function uses the `Lt` (less than) method of `*u256.Uint` to perform the comparison.
 83//   - The function assumes both input values are non-nil. If nil inputs are possible in the usage context,
 84//     additional validation may be needed.
 85//
 86// Example:
 87// smaller := u256Min(u256.MustFromDecimal("10"), u256.MustFromDecimal("20")) // Returns 10
 88// smaller := u256Min(u256.MustFromDecimal("30"), u256.MustFromDecimal("20")) // Returns 20
 89func u256Min(num1, num2 *u256.Uint) *u256.Uint {
 90	if num1.Lt(num2) {
 91		return num1
 92	}
 93	return num2
 94}
 95
 96// checkOverFlowInt128 checks if the value overflows the int128 range.
 97func checkOverFlowInt128(value *i256.Int) {
 98	if value.Gt(maxInt128FromDecimal) || value.Lt(minInt128FromDecimal) {
 99		panic(ufmt.Sprintf(
100			"%v: amount(%s) overflows int128 range",
101			errOverflow, value.ToString(),
102		))
103	}
104}
105
106// checkTickSpacing checks if the tick is divisible by the tickSpacing.
107func checkTickSpacing(tick, tickSpacing int32) {
108	if tick%tickSpacing != 0 {
109		panic(newErrorWithDetail(
110			errInvalidTickAndTickSpacing,
111			ufmt.Sprintf("tick(%d) MOD tickSpacing(%d) != 0(%d)", tick, tickSpacing, tick%tickSpacing),
112		))
113	}
114}