halving.gno
6.28 Kb · 227 lines
1package gns
2
3import (
4 gnsmath "gno.land/p/gnoswap/gnsmath/v1"
5)
6
7// HalvingData stores emission data for each halving period.
8// Contains timestamps, amounts, and rates for the 12-year emission schedule.
9type HalvingData struct {
10 startTimestamps []int64
11 endTimestamps []int64
12 maxAmount []int64
13 leftAmount []int64
14 mintedAmount []int64
15 amountPerSecond []int64
16}
17
18// getStartTimestamp returns the start timestamp for the specified halving year.
19// Returns 0 if year is invalid.
20func (h *HalvingData) getStartTimestamp(year int64) int64 {
21 if validYear(year) != nil {
22 return 0
23 }
24
25 return h.startTimestamps[year-1]
26}
27
28// getEndTimestamp returns the end timestamp for the specified halving year.
29// Returns 0 if year is invalid.
30func (h *HalvingData) getEndTimestamp(year int64) int64 {
31 if validYear(year) != nil {
32 return 0
33 }
34
35 return h.endTimestamps[year-1]
36}
37
38// getMaxAmount returns the maximum emission amount for the specified halving year.
39// Returns 0 if year is invalid.
40func (h *HalvingData) getMaxAmount(year int64) int64 {
41 if validYear(year) != nil {
42 return 0
43 }
44
45 return h.maxAmount[year-1]
46}
47
48// getMintedAmount returns the minted emission amount for the specified halving year.
49func (h *HalvingData) getMintedAmount(year int64) int64 {
50 if validYear(year) != nil {
51 return 0
52 }
53 return h.mintedAmount[year-1]
54}
55
56// getLeftAmount returns the remaining emission amount for the specified halving year.
57func (h *HalvingData) getLeftAmount(year int64) int64 {
58 if validYear(year) != nil {
59 return 0
60 }
61 return h.leftAmount[year-1]
62}
63
64// getAmountPerSecond returns the emission rate per second for the specified halving year.
65// Returns 0 if year is invalid.
66func (h *HalvingData) getAmountPerSecond(year int64) int64 {
67 if validYear(year) != nil {
68 return 0
69 }
70 return h.amountPerSecond[year-1]
71}
72
73// setStartTimestamp sets the start timestamp for the specified halving year.
74// Returns error if year is invalid.
75func (h *HalvingData) setStartTimestamp(year int64, timestamp int64) error {
76 err := validYear(year)
77 if err != nil {
78 return err
79 }
80
81 h.startTimestamps[year-1] = timestamp
82
83 return nil
84}
85
86// setEndTimestamp sets the end timestamp for the specified halving year.
87// Returns error if year is invalid.
88func (h *HalvingData) setEndTimestamp(year int64, timestamp int64) error {
89 err := validYear(year)
90 if err != nil {
91 return err
92 }
93
94 h.endTimestamps[year-1] = timestamp
95
96 return nil
97}
98
99// setMaxAmount sets the maximum emission amount for the specified halving year.
100// Returns error if year is invalid.
101func (h *HalvingData) setMaxAmount(year, amount int64) error {
102 err := validYear(year)
103 if err != nil {
104 return err
105 }
106
107 h.maxAmount[year-1] = amount
108
109 return nil
110}
111
112// setMintedAmount sets the minted amount for the specified halving year.
113// Returns error if year is invalid.
114func (h *HalvingData) setMintedAmount(year, amount int64) error {
115 err := validYear(year)
116 if err != nil {
117 return err
118 }
119
120 h.mintedAmount[year-1] = amount
121
122 return nil
123}
124
125// setLeftAmount sets the remaining amount for the specified halving year.
126// Returns error if year is invalid.
127func (h *HalvingData) setLeftAmount(year, amount int64) error {
128 err := validYear(year)
129 if err != nil {
130 return err
131 }
132
133 h.leftAmount[year-1] = amount
134
135 return nil
136}
137
138// addMintedAmount adds to the minted amount for the specified halving year.
139// Returns error if year is invalid.
140func (h *HalvingData) addMintedAmount(year, amount int64) error {
141 err := validYear(year)
142 if err != nil {
143 return err
144 }
145
146 h.mintedAmount[year-1] = gnsmath.SafeAddInt64(h.mintedAmount[year-1], amount)
147
148 return nil
149}
150
151// setAmountPerSecond sets the emission rate per second for the specified halving year.
152// Returns error if year is invalid.
153func (h *HalvingData) setAmountPerSecond(year, amount int64) error {
154 err := validYear(year)
155 if err != nil {
156 return err
157 }
158
159 h.amountPerSecond[year-1] = amount
160
161 return nil
162}
163
164// Clone creates a deep copy of all halving schedule slices.
165//
166// Returns:
167// - halvingData: independent copy of timestamps, allocations, minted amounts, remaining amounts, and rates
168func (h *HalvingData) Clone() *HalvingData {
169 startTimestamps := make([]int64, len(h.startTimestamps))
170 endTimestamps := make([]int64, len(h.endTimestamps))
171 maxAmount := make([]int64, len(h.maxAmount))
172 leftAmount := make([]int64, len(h.leftAmount))
173 mintedAmount := make([]int64, len(h.mintedAmount))
174 amountPerSecond := make([]int64, len(h.amountPerSecond))
175
176 copy(startTimestamps, h.startTimestamps)
177 copy(endTimestamps, h.endTimestamps)
178 copy(maxAmount, h.maxAmount)
179 copy(leftAmount, h.leftAmount)
180 copy(mintedAmount, h.mintedAmount)
181 copy(amountPerSecond, h.amountPerSecond)
182
183 return &HalvingData{
184 startTimestamps: startTimestamps,
185 endTimestamps: endTimestamps,
186 maxAmount: maxAmount,
187 leftAmount: leftAmount,
188 mintedAmount: mintedAmount,
189 amountPerSecond: amountPerSecond,
190 }
191}
192
193// NewHalvingData creates a 12-year HalvingData emission schedule starting at
194// startTimestamp. Each year receives configured timestamps, allocation, zero
195// minted amount, remaining allocation, and an integer-truncated per-second rate.
196//
197// Parameters:
198// - startTimestamp: Unix timestamp at which halving year 1 begins
199//
200// Returns:
201// - halvingData: initialized schedule with years [1, 12] and their derived values
202func NewHalvingData(startTimestamp int64) *HalvingData {
203 halvingData := &HalvingData{
204 startTimestamps: make([]int64, HALVING_END_YEAR),
205 endTimestamps: make([]int64, HALVING_END_YEAR),
206 maxAmount: make([]int64, HALVING_END_YEAR),
207 leftAmount: make([]int64, HALVING_END_YEAR),
208 mintedAmount: make([]int64, HALVING_END_YEAR),
209 amountPerSecond: make([]int64, HALVING_END_YEAR),
210 }
211
212 for year := HALVING_START_YEAR; year <= HALVING_END_YEAR; year++ {
213 yearStartTimestamp := startTimestamp + (SECONDS_IN_YEAR * (year - 1))
214 yearEndTimestamp := yearStartTimestamp + SECONDS_IN_YEAR - 1
215 yearDistributionAmount := GetHalvingAmountsPerYear(year)
216 yearAmountPerSecond := yearDistributionAmount / SECONDS_IN_YEAR
217
218 halvingData.setStartTimestamp(year, yearStartTimestamp)
219 halvingData.setEndTimestamp(year, yearEndTimestamp)
220 halvingData.setMaxAmount(year, yearDistributionAmount)
221 halvingData.setMintedAmount(year, 0)
222 halvingData.setAmountPerSecond(year, yearAmountPerSecond)
223 halvingData.setLeftAmount(year, yearDistributionAmount)
224 }
225
226 return halvingData
227}