Search Apps Documentation Source Content File Folder Download Copy Actions Download 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}