@@ -22,65 +22,73 @@ const (
22
22
)
23
23
24
24
var (
25
- lastMintedHeight = std.GetHeight()
26
- )
25
+ owner *ownable.Ownable
27
26
28
- var (
29
- // Initial amount set to 900_000_000_000_000 (MAXIMUM_SUPPLY - INITIAL_MINT_AMOUNT).
30
- // leftEmissionAmount will decrease as tokens are minted.
31
- leftEmissionAmount = MAX_EMISSION_AMOUNT
32
- mintedEmissionAmount = uint64(0)
33
- )
27
+ Token *grc20.Token
28
+ privateLedger *grc20.PrivateLedger
29
+ UserTeller grc20.Teller
34
30
35
- var (
36
- Token, privateLedger = grc20.NewToken("Gnoswap", "GNS", 6)
37
- UserTeller = Token.CallerTeller()
38
- owner = ownable.NewWithAddress(consts.ADMIN)
31
+ leftEmissionAmount uint64
32
+ mintedEmissionAmount uint64
33
+ lastMintedHeight int64
34
+
35
+ burnAmount uint64
39
36
)
40
37
41
38
func init() {
39
+ owner = ownable.NewWithAddress(consts.ADMIN)
40
+
41
+ Token, privateLedger = grc20.NewToken("Gnoswap", "GNS", 6)
42
+ UserTeller = Token.CallerTeller()
43
+
42
44
privateLedger.Mint(owner.Owner(), INITIAL_MINT_AMOUNT)
43
45
getter := func() *grc20.Token { return Token }
44
46
grc20reg.Register(getter, "")
45
- }
46
47
47
- // MintedEmissionAmount returns the amount of GNS that has been minted by the emission contract.
48
- // It does not include initial minted amount.
49
- func MintedEmissionAmount() uint64 {
50
- return TotalSupply() - INITIAL_MINT_AMOUNT
48
+ // Initial amount set to 900_000_000_000_000 (MAXIMUM_SUPPLY - INITIAL_MINT_AMOUNT).
49
+ // leftEmissionAmount will decrease as tokens are minted.
50
+ leftEmissionAmount = MAX_EMISSION_AMOUNT
51
+
52
+ lastMintedHeight = std.GetHeight()
51
53
}
52
54
53
55
func MintGns(address pusers.AddressOrName) uint64 {
54
56
lastMintedHeight := GetLastMintedHeight()
55
57
currentHeight := std.GetHeight()
56
58
57
- // skip minting process if gns for current block is already minted
58
- if skipIfSameHeight(lastMintedHeight, currentHeight) {
59
+ // skip minting process if following conditions are met
60
+ // - if gns for current block is already minted
61
+ // - if last minted height is same or later than emission end height
62
+ if lastMintedHeight == currentHeight || lastMintedHeight >= GetEndHeight() {
59
63
return 0
60
64
}
61
65
62
66
assertShouldNotBeHalted()
63
67
assertCallerIsEmission()
64
68
65
- // calculate gns amount to mint, and the mint to the target address
69
+ // calculate gns amount to mint
66
70
amountToMint := calculateAmountToMint(lastMintedHeight+1, currentHeight)
67
- err := privateLedger.Mint(users.Resolve(address), amountToMint)
68
- if err != nil {
69
- panic(err.Error())
70
- }
71
71
72
72
// update
73
73
setLastMintedHeight(currentHeight)
74
74
setMintedEmissionAmount(GetMintedEmissionAmount() + amountToMint)
75
75
setLeftEmissionAmount(GetLeftEmissionAmount() - amountToMint)
76
76
77
+ // mint calculated amount to address
78
+ err := privateLedger.Mint(users.Resolve(address), amountToMint)
79
+ if err != nil {
80
+ panic(err.Error())
81
+ }
82
+
77
83
return amountToMint
78
84
}
79
85
80
86
func Burn(from pusers.AddressOrName, amount uint64) {
81
87
owner.AssertCallerIsOwner()
82
88
fromAddr := users.Resolve(from)
83
89
checkErr(privateLedger.Burn(fromAddr, amount))
90
+
91
+ burnAmount += amount
84
92
}
85
93
86
94
func TotalSupply() uint64 {
@@ -137,60 +145,60 @@ func checkErr(err error) {
137
145
}
138
146
}
139
147
140
- // helper functions
141
-
142
148
// calculateAmountToMint calculates the amount of gns to mint
143
149
// It calculates the amount of gns to mint for each halving year for block range.
144
150
// It also handles the left emission amount if the current block range includes halving year end block.
145
151
func calculateAmountToMint(fromHeight, toHeight int64) uint64 {
146
152
fromYear := GetHalvingYearByHeight(fromHeight)
147
- toYear := GetHalvingYearByHeight(toHeight)
148
153
149
- if isEmissionEnded(fromYear) || isEmissionEnded(toYear) {
150
- return 0
154
+ // if toHeight is greater than emission end height, set toHeight to emission end height
155
+ if toHeight > GetEndHeight() {
156
+ toHeight = GetEndHeight()
151
157
}
158
+ toYear := GetHalvingYearByHeight(toHeight)
152
159
153
160
totalAmountToMint := uint64(0)
154
161
155
- for i := fromYear; i <= toYear; i ++ {
156
- yearEndHeight := GetHalvingYearBlock(i )
162
+ for year := fromYear; year <= toYear; year ++ {
163
+ yearEndHeight := GetHalvingYearEndBlock(year )
157
164
mintUntilHeight := i64Min(yearEndHeight, toHeight)
158
165
159
166
// how many blocks to calculate
160
167
blocks := uint64(mintUntilHeight-fromHeight) + 1
161
168
162
169
// amount of gns to mint for each block for current year
163
- singleBlockAmount := GetAmountByHeight(yearEndHeight )
170
+ singleBlockAmount := GetAmountPerBlockPerHalvingYear(year )
164
171
165
172
// amount of gns to mint for current year
166
173
yearAmountToMint := singleBlockAmount * blocks
167
174
168
175
// if last block of halving year, handle left emission amount
169
176
if isLastBlockOfHalvingYear(mintUntilHeight) {
170
- yearAmountToMint += handleLeftEmissionAmount(i , yearAmountToMint)
177
+ yearAmountToMint += handleLeftEmissionAmount(year , yearAmountToMint)
171
178
}
172
179
totalAmountToMint += yearAmountToMint
173
- SetHalvingYearMintAmount(i , GetHalvingYearMintAmount(i )+yearAmountToMint)
180
+ setHalvingYearMintAmount(year , GetHalvingYearMintAmount(year )+yearAmountToMint)
174
181
175
182
// update fromHeight for next year (if necessary)
176
183
fromHeight = mintUntilHeight + 1
177
184
}
178
185
186
+ assertTooManyEmission(totalAmountToMint)
179
187
return totalAmountToMint
180
188
}
181
189
182
190
// isLastBlockOfHalvingYear returns true if the current block is the last block of a halving year.
183
191
func isLastBlockOfHalvingYear(height int64) bool {
184
192
year := GetHalvingYearByHeight(height)
185
- lastBlock := GetHalvingYearBlock (year)
193
+ lastBlock := GetHalvingYearEndBlock (year)
186
194
187
195
return height == lastBlock
188
196
}
189
197
190
198
// handleLeftEmissionAmount handles the left emission amount for a halving year.
191
199
// It calculates the left emission amount by subtracting the halving year mint amount from the halving year amount.
192
200
func handleLeftEmissionAmount(year int64, amount uint64) uint64 {
193
- return GetHalvingYearAmount (year) - GetHalvingYearMintAmount(year) - amount
201
+ return GetHalvingYearMaxAmount (year) - GetHalvingYearMintAmount(year) - amount
194
202
}
195
203
196
204
// skipIfSameHeight returns true if the current block height is the same as the last minted height.
@@ -199,30 +207,36 @@ func skipIfSameHeight(lastMintedHeight, currentHeight int64) bool {
199
207
return lastMintedHeight == currentHeight
200
208
}
201
209
202
- // isEmissionEnded returns true if the emission is ended.
203
- // It returns false if the emission is not ended.
204
- func isEmissionEnded(year int64) bool {
205
- if 1 <= year && year <= 12 {
206
- return false
210
+ // skipIfEmissionEnded returns true if the emission has ended.
211
+ func skipIfEmissionEnded(height int64) bool {
212
+ if isEmissionEnded(height) {
213
+ return true
207
214
}
208
215
209
- return true
216
+ return false
210
217
}
211
218
212
- // Getter
219
+ // GetLastMintedHeight returns the last block height that gns was minted.
213
220
func GetLastMintedHeight() int64 {
214
221
return lastMintedHeight
215
222
}
216
223
224
+ // GetLeftEmissionAmount returns the amount of GNS can be minted.
217
225
func GetLeftEmissionAmount() uint64 {
218
226
return leftEmissionAmount
219
227
}
220
228
229
+ // GetBurnAmount returns the amount of GNS that has been burned.
230
+ func GetBurnAmount() uint64 {
231
+ return burnAmount
232
+ }
233
+
234
+ // GetMintedEmissionAmount returns the amount of GNS that has been minted by the emission contract.
235
+ // It does not include initial minted amount.
221
236
func GetMintedEmissionAmount() uint64 {
222
237
return mintedEmissionAmount
223
238
}
224
239
225
- // Setter
226
240
func setLastMintedHeight(height int64) {
227
241
lastMintedHeight = height
228
242
}
@@ -234,3 +248,14 @@ func setLeftEmissionAmount(amount uint64) {
234
248
func setMintedEmissionAmount(amount uint64) {
235
249
mintedEmissionAmount = amount
236
250
}
251
+
252
+ // assertTooManyEmission asserts if the amount of gns to mint is too many.
253
+ // It checks if the amount of gns to mint is greater than the left emission amount or the total emission amount.
254
+ func assertTooManyEmission(amount uint64) {
255
+ if amount > GetLeftEmissionAmount() || (amount+GetMintedEmissionAmount()) > MAX_EMISSION_AMOUNT {
256
+ panic(addDetailToError(
257
+ errTooManyEmission,
258
+ ufmt.Sprintf("amount: %d", amount),
259
+ ))
260
+ }
261
+ }
0 commit comments