utils.gno
2.55 Kb · 104 lines
1package gns
2
3import (
4 "math"
5 "strconv"
6
7 ufmt "gno.land/p/nt/ufmt/v0"
8)
9
10// validYear validates that year is within halving period range (1-12).
11// Returns error if year is outside the valid range.
12func validYear(year int64) error {
13 if year < HALVING_START_YEAR || year > HALVING_END_YEAR {
14 return makeErrorWithDetails(errInvalidYear, ufmt.Sprintf("year: %d", year))
15 }
16
17 return nil
18}
19
20// validEmissionAmount validates that the emission amount does not exceed maximum.
21// Returns error if minting the amount would exceed MAX_EMISSION_AMOUNT.
22func validEmissionAmount(amount int64) error {
23 if amount < 0 {
24 return makeErrorWithDetails(errInvalidEmissionAmount, ufmt.Sprintf("emission amount cannot be negative: %d", amount))
25 }
26
27 if safeAddInt64(amount, MintedEmissionAmount()) > MAX_EMISSION_AMOUNT {
28 return makeErrorWithDetails(errTooManyEmission, ufmt.Sprintf("too many emission amount: %d", amount))
29 }
30
31 return nil
32}
33
34// i64Min returns the smaller of two int64 values.
35func i64Min(x, y int64) int64 {
36 if x < y {
37 return x
38 }
39 return y
40}
41
42// formatInt formats signed integer types to string.
43// Supports int32, int64, and int. Panics for unsupported types.
44func formatInt(v any) string {
45 switch v := v.(type) {
46 case int32:
47 return strconv.FormatInt(int64(v), 10)
48 case int64:
49 return strconv.FormatInt(v, 10)
50 case int:
51 return strconv.Itoa(v)
52 default:
53 panic(ufmt.Sprintf("invalid type: %T", v))
54 }
55}
56
57// safeAddInt64 performs safe addition of int64 values, panicking on overflow or underflow
58func safeAddInt64(a, b int64) int64 {
59 if a > 0 && b > math.MaxInt64-a {
60 panic("int64 addition overflow")
61 }
62 if a < 0 && b < math.MinInt64-a {
63 panic("int64 addition underflow")
64 }
65 return a + b
66}
67
68// safeSubInt64 performs safe subtraction of int64 values, panicking on overflow or underflow
69func safeSubInt64(a, b int64) int64 {
70 if b > 0 && a < math.MinInt64+b {
71 panic("int64 subtraction underflow")
72 }
73 if b < 0 && a > math.MaxInt64+b {
74 panic("int64 subtraction overflow")
75 }
76 return a - b
77}
78
79// safeMulInt64 performs safe multiplication of int64 values, panicking on overflow or underflow
80func safeMulInt64(a, b int64) int64 {
81 if a == 0 || b == 0 {
82 return 0
83 }
84
85 if a > 0 && b > 0 {
86 if a > math.MaxInt64/b {
87 panic("int64 multiplication overflow")
88 }
89 } else if a < 0 && b < 0 {
90 if a < math.MaxInt64/b {
91 panic("int64 multiplication overflow")
92 }
93 } else if a > 0 && b < 0 {
94 if b < math.MinInt64/a {
95 panic("int64 multiplication underflow")
96 }
97 } else { // a < 0 && b > 0
98 if a < math.MinInt64/b {
99 panic("int64 multiplication underflow")
100 }
101 }
102
103 return a * b
104}