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