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}