@@ -12,14 +12,29 @@ const indirectContract = contracts.sip031Indirect;
12
12
* "Mint" STX to the contract
13
13
*/
14
14
function mint ( amount : number | bigint ) {
15
- txOk ( indirectContract . transferStx ( amount , contract . identifier ) , accounts . wallet_4 . address ) ;
15
+ txOk (
16
+ indirectContract . transferStx ( amount , contract . identifier ) ,
17
+ accounts . wallet_4 . address ,
18
+ ) ;
16
19
}
17
20
18
21
// Helper function to mint the initial 200M STX to the contract
19
22
function mintInitial ( ) {
20
23
// First make sure wallet_4 has enough STX to mint the initial amount
21
- txOk ( indirectContract . transferStx ( constants . INITIAL_MINT_AMOUNT / 2n , accounts . wallet_4 . address ) , accounts . wallet_5 . address ) ;
22
- txOk ( indirectContract . transferStx ( constants . INITIAL_MINT_AMOUNT / 2n , accounts . wallet_4 . address ) , accounts . wallet_6 . address ) ;
24
+ txOk (
25
+ indirectContract . transferStx (
26
+ constants . INITIAL_MINT_AMOUNT / 2n ,
27
+ accounts . wallet_4 . address ,
28
+ ) ,
29
+ accounts . wallet_5 . address ,
30
+ ) ;
31
+ txOk (
32
+ indirectContract . transferStx (
33
+ constants . INITIAL_MINT_AMOUNT / 2n ,
34
+ accounts . wallet_4 . address ,
35
+ ) ,
36
+ accounts . wallet_6 . address ,
37
+ ) ;
23
38
// Mint the entire INITIAL_MINT_AMOUNT to the vesting contract
24
39
mint ( constants . INITIAL_MINT_AMOUNT ) ;
25
40
}
@@ -31,36 +46,51 @@ function months(n: number) {
31
46
test ( 'initial recipient should be the deployer' , ( ) => {
32
47
const value = rov ( contract . getRecipient ( ) ) ;
33
48
expect ( value ) . toBe ( accounts . deployer . address ) ;
34
- } )
49
+ } ) ;
35
50
36
51
test ( 'only the recipient can update the recipient' , ( ) => {
37
- const receipt = txErr ( contract . updateRecipient ( accounts . wallet_1 . address ) , accounts . wallet_1 . address )
52
+ const receipt = txErr (
53
+ contract . updateRecipient ( accounts . wallet_1 . address ) ,
54
+ accounts . wallet_1 . address ,
55
+ ) ;
38
56
39
57
expect ( receipt . value ) . toBe ( constants . ERR_NOT_ALLOWED ) ;
40
58
} ) ;
41
59
42
60
test ( 'recipient can update the recipient' , ( ) => {
43
- txOk ( contract . updateRecipient ( accounts . wallet_1 . address ) , accounts . deployer . address )
61
+ txOk (
62
+ contract . updateRecipient ( accounts . wallet_1 . address ) ,
63
+ accounts . deployer . address ,
64
+ ) ;
44
65
45
66
const value = rov ( contract . getRecipient ( ) ) ;
46
67
expect ( value ) . toBe ( accounts . wallet_1 . address ) ;
47
68
} ) ;
48
69
49
70
test ( 'updated recipient can re-update the recipient' , ( ) => {
50
- txOk ( contract . updateRecipient ( accounts . wallet_1 . address ) , accounts . deployer . address )
71
+ txOk (
72
+ contract . updateRecipient ( accounts . wallet_1 . address ) ,
73
+ accounts . deployer . address ,
74
+ ) ;
51
75
expect ( rov ( contract . getRecipient ( ) ) ) . toBe ( accounts . wallet_1 . address ) ;
52
76
53
- txOk ( contract . updateRecipient ( accounts . wallet_2 . address ) , accounts . wallet_1 . address )
77
+ txOk (
78
+ contract . updateRecipient ( accounts . wallet_2 . address ) ,
79
+ accounts . wallet_1 . address ,
80
+ ) ;
54
81
expect ( rov ( contract . getRecipient ( ) ) ) . toBe ( accounts . wallet_2 . address ) ;
55
82
} ) ;
56
83
57
84
test ( 'recipient cannot be updated from an indirect contract' , ( ) => {
58
- const receipt = txErr ( indirectContract . updateRecipient ( accounts . wallet_1 . address ) , accounts . deployer . address )
85
+ const receipt = txErr (
86
+ indirectContract . updateRecipient ( accounts . wallet_1 . address ) ,
87
+ accounts . deployer . address ,
88
+ ) ;
59
89
expect ( receipt . value ) . toBe ( constants . ERR_NOT_ALLOWED ) ;
60
90
} ) ;
61
91
62
92
test ( 'errors if claiming as a non-recipient' , ( ) => {
63
- const receipt = txErr ( contract . claim ( ) , accounts . wallet_1 . address )
93
+ const receipt = txErr ( contract . claim ( ) , accounts . wallet_1 . address ) ;
64
94
expect ( receipt . value ) . toBe ( constants . ERR_NOT_ALLOWED ) ;
65
95
} ) ;
66
96
@@ -69,7 +99,10 @@ test('initial recipient can claim', () => {
69
99
const receipt = txOk ( contract . claim ( ) , accounts . deployer . address ) ;
70
100
expect ( receipt . value ) . toBe ( constants . INITIAL_MINT_IMMEDIATE_AMOUNT ) ;
71
101
72
- const [ event ] = filterEvents ( receipt . events , CoreNodeEventType . StxTransferEvent ) ;
102
+ const [ event ] = filterEvents (
103
+ receipt . events ,
104
+ CoreNodeEventType . StxTransferEvent ,
105
+ ) ;
73
106
expect ( event . data . amount ) . toBe ( `${ constants . INITIAL_MINT_IMMEDIATE_AMOUNT } ` ) ;
74
107
expect ( event . data . recipient ) . toBe ( accounts . deployer . address ) ;
75
108
expect ( event . data . sender ) . toBe ( contract . identifier ) ;
@@ -81,12 +114,18 @@ test('updated recipient can claim', () => {
81
114
const balance = rov ( indirectContract . getBalance ( contract . identifier ) ) ;
82
115
expect ( balance ) . toBe ( constants . INITIAL_MINT_AMOUNT ) ;
83
116
84
- txOk ( contract . updateRecipient ( accounts . wallet_1 . address ) , accounts . deployer . address ) ;
117
+ txOk (
118
+ contract . updateRecipient ( accounts . wallet_1 . address ) ,
119
+ accounts . deployer . address ,
120
+ ) ;
85
121
const receipt = txOk ( contract . claim ( ) , accounts . wallet_1 . address ) ;
86
122
expect ( receipt . value ) . toBe ( constants . INITIAL_MINT_IMMEDIATE_AMOUNT ) ;
87
123
88
124
expect ( receipt . events . length ) . toBe ( 2 ) ;
89
- const stxTransferEvents = filterEvents ( receipt . events , CoreNodeEventType . StxTransferEvent ) ;
125
+ const stxTransferEvents = filterEvents (
126
+ receipt . events ,
127
+ CoreNodeEventType . StxTransferEvent ,
128
+ ) ;
90
129
expect ( stxTransferEvents . length ) . toBe ( 1 ) ;
91
130
const [ event ] = stxTransferEvents ;
92
131
expect ( event . data . amount ) . toBe ( `${ constants . INITIAL_MINT_IMMEDIATE_AMOUNT } ` ) ;
@@ -109,19 +148,27 @@ test('calculating vested amounts at a block height', () => {
109
148
return immediateAmount + vestingAmount ;
110
149
}
111
150
112
- expect ( rov ( contract . calcClaimableAmount ( deployBlockHeight ) ) ) . toBe ( immediateAmount ) ;
151
+ expect ( rov ( contract . calcClaimableAmount ( deployBlockHeight ) ) ) . toBe (
152
+ immediateAmount ,
153
+ ) ;
113
154
114
155
function expectAmount ( month : bigint ) {
115
156
const burnHeight = deployBlockHeight + month * 4383n ;
116
- expect ( rov ( contract . calcClaimableAmount ( burnHeight ) ) ) . toBe ( expectedAmount ( burnHeight ) ) ;
157
+ expect ( rov ( contract . calcClaimableAmount ( burnHeight ) ) ) . toBe (
158
+ expectedAmount ( burnHeight ) ,
159
+ ) ;
117
160
}
118
161
119
162
for ( let i = 1n ; i < 24n ; i ++ ) {
120
163
expectAmount ( i ) ;
121
164
}
122
165
// At 24+ months, the entire vesting bucket should be unlocked
123
- expect ( rov ( contract . calcClaimableAmount ( deployBlockHeight + 24n * 4383n ) ) ) . toBe ( initialMintAmount ) ;
124
- expect ( rov ( contract . calcClaimableAmount ( deployBlockHeight + 25n * 4383n ) ) ) . toBe ( initialMintAmount ) ;
166
+ expect (
167
+ rov ( contract . calcClaimableAmount ( deployBlockHeight + 24n * 4383n ) ) ,
168
+ ) . toBe ( initialMintAmount ) ;
169
+ expect (
170
+ rov ( contract . calcClaimableAmount ( deployBlockHeight + 25n * 4383n ) ) ,
171
+ ) . toBe ( initialMintAmount ) ;
125
172
} ) ;
126
173
127
174
// -----------------------------------------------------------------------------
@@ -135,10 +182,16 @@ test('claim scenario 1', () => {
135
182
mint ( 100n * 1000000n ) ;
136
183
simnet . mineEmptyBlocks ( months ( 1 ) ) ;
137
184
const receipt = txOk ( contract . claim ( ) , accounts . deployer . address ) ;
138
- const expected = constants . INITIAL_MINT_IMMEDIATE_AMOUNT + constants . INITIAL_MINT_VESTING_AMOUNT / 24n + 100n * 1000000n ;
185
+ const expected =
186
+ constants . INITIAL_MINT_IMMEDIATE_AMOUNT +
187
+ constants . INITIAL_MINT_VESTING_AMOUNT / 24n +
188
+ 100n * 1000000n ;
139
189
expect ( receipt . value ) . toBe ( expected ) ;
140
190
141
- const [ event ] = filterEvents ( receipt . events , CoreNodeEventType . StxTransferEvent ) ;
191
+ const [ event ] = filterEvents (
192
+ receipt . events ,
193
+ CoreNodeEventType . StxTransferEvent ,
194
+ ) ;
142
195
expect ( event . data . amount ) . toBe ( expected . toString ( ) ) ;
143
196
expect ( event . data . recipient ) . toBe ( accounts . deployer . address ) ;
144
197
expect ( event . data . sender ) . toBe ( contract . identifier ) ;
@@ -147,24 +200,31 @@ test('claim scenario 1', () => {
147
200
mint ( 500n * 1000000n ) ;
148
201
simnet . mineEmptyBlocks ( months ( 4 ) ) ;
149
202
const receipt2 = txOk ( contract . claim ( ) , accounts . deployer . address ) ;
150
- const expected2 = constants . INITIAL_MINT_VESTING_AMOUNT / 24n * 4n + 500n * 1000000n ;
203
+ const expected2 =
204
+ ( constants . INITIAL_MINT_VESTING_AMOUNT / 24n ) * 4n + 500n * 1000000n ;
151
205
expect ( receipt2 . value ) . toBe ( expected2 ) ;
152
206
153
- const [ event2 ] = filterEvents ( receipt2 . events , CoreNodeEventType . StxTransferEvent ) ;
207
+ const [ event2 ] = filterEvents (
208
+ receipt2 . events ,
209
+ CoreNodeEventType . StxTransferEvent ,
210
+ ) ;
154
211
expect ( event2 . data . amount ) . toBe ( expected2 . toString ( ) ) ;
155
212
expect ( event2 . data . recipient ) . toBe ( accounts . deployer . address ) ;
156
213
157
214
// wait until end of vesting (20 more months), with an extra 1500 STX
158
215
// calc remainder of unvested, to deal with integer division
159
- const vestedAlready = constants . INITIAL_MINT_VESTING_AMOUNT / 24n * 5n ;
216
+ const vestedAlready = ( constants . INITIAL_MINT_VESTING_AMOUNT / 24n ) * 5n ;
160
217
const unvested = constants . INITIAL_MINT_VESTING_AMOUNT - vestedAlready ;
161
218
const expected3 = unvested + 1500n * 1000000n ;
162
219
mint ( 1500n * 1000000n ) ;
163
220
simnet . mineEmptyBlocks ( months ( 20 ) ) ;
164
221
const receipt3 = txOk ( contract . claim ( ) , accounts . deployer . address ) ;
165
222
expect ( receipt3 . value ) . toBe ( expected3 ) ;
166
223
167
- const [ event3 ] = filterEvents ( receipt3 . events , CoreNodeEventType . StxTransferEvent ) ;
224
+ const [ event3 ] = filterEvents (
225
+ receipt3 . events ,
226
+ CoreNodeEventType . StxTransferEvent ,
227
+ ) ;
168
228
expect ( event3 . data . amount ) . toBe ( expected3 . toString ( ) ) ;
169
229
expect ( event3 . data . recipient ) . toBe ( accounts . deployer . address ) ;
170
230
@@ -176,11 +236,14 @@ test('claim scenario 1', () => {
176
236
const receipt4 = txOk ( contract . claim ( ) , accounts . deployer . address ) ;
177
237
expect ( receipt4 . value ) . toBe ( expected4 ) ;
178
238
179
- const [ event4 ] = filterEvents ( receipt4 . events , CoreNodeEventType . StxTransferEvent ) ;
239
+ const [ event4 ] = filterEvents (
240
+ receipt4 . events ,
241
+ CoreNodeEventType . StxTransferEvent ,
242
+ ) ;
180
243
expect ( event4 . data . amount ) . toBe ( expected4 . toString ( ) ) ;
181
244
expect ( event4 . data . recipient ) . toBe ( accounts . deployer . address ) ;
182
245
expect ( rov ( indirectContract . getBalance ( contract . identifier ) ) ) . toBe ( 0n ) ;
183
- } )
246
+ } ) ;
184
247
185
248
// -----------------------------------------------------------------------------
186
249
// Edge-case: Claim when the contract holds *zero* balance should revert
@@ -233,7 +296,9 @@ test('final vesting iteration flushes rounding remainder', () => {
233
296
simnet . mineEmptyBlocks ( months ( 23 ) ) ;
234
297
235
298
// First claim: immediate bucket + 23/24 of vesting bucket
236
- const perIteration = constants . INITIAL_MINT_VESTING_AMOUNT / constants . INITIAL_MINT_VESTING_ITERATIONS ;
299
+ const perIteration =
300
+ constants . INITIAL_MINT_VESTING_AMOUNT /
301
+ constants . INITIAL_MINT_VESTING_ITERATIONS ;
237
302
const expectedFirst =
238
303
constants . INITIAL_MINT_IMMEDIATE_AMOUNT + perIteration * 23n ;
239
304
const first = txOk ( contract . claim ( ) , accounts . deployer . address ) ;
@@ -266,20 +331,28 @@ test('new recipient claims vested tranche plus extra deposit', () => {
266
331
simnet . mineEmptyBlocks ( months ( 1 ) ) ;
267
332
268
333
// Update recipient to wallet_1
269
- txOk ( contract . updateRecipient ( accounts . wallet_1 . address ) , accounts . deployer . address ) ;
334
+ txOk (
335
+ contract . updateRecipient ( accounts . wallet_1 . address ) ,
336
+ accounts . deployer . address ,
337
+ ) ;
270
338
271
339
// External party deposits 500 STX
272
340
const extraDeposit = 500n * 1000000n ;
273
341
mint ( extraDeposit ) ;
274
342
275
343
// Wallet_1 claims: should receive 1/24 of vesting bucket + 500 STX
276
- const perIteration = constants . INITIAL_MINT_VESTING_AMOUNT / constants . INITIAL_MINT_VESTING_ITERATIONS ;
344
+ const perIteration =
345
+ constants . INITIAL_MINT_VESTING_AMOUNT /
346
+ constants . INITIAL_MINT_VESTING_ITERATIONS ;
277
347
const expected = perIteration + extraDeposit ;
278
348
const receipt = txOk ( contract . claim ( ) , accounts . wallet_1 . address ) ;
279
349
expect ( receipt . value ) . toBe ( expected ) ;
280
350
281
351
// Validate transfer event
282
- const [ evt ] = filterEvents ( receipt . events , CoreNodeEventType . StxTransferEvent ) ;
352
+ const [ evt ] = filterEvents (
353
+ receipt . events ,
354
+ CoreNodeEventType . StxTransferEvent ,
355
+ ) ;
283
356
expect ( evt . data . amount ) . toBe ( expected . toString ( ) ) ;
284
357
expect ( evt . data . recipient ) . toBe ( accounts . wallet_1 . address ) ;
285
358
expect ( evt . data . sender ) . toBe ( contract . identifier ) ;
@@ -292,7 +365,10 @@ test('calculating claimable amount at invalid block height returns 0', () => {
292
365
} ) ;
293
366
294
367
test ( 'print events are emitted when updating recipient' , ( ) => {
295
- const receipt = txOk ( contract . updateRecipient ( accounts . wallet_1 . address ) , accounts . deployer . address ) ;
368
+ const receipt = txOk (
369
+ contract . updateRecipient ( accounts . wallet_1 . address ) ,
370
+ accounts . deployer . address ,
371
+ ) ;
296
372
expect ( receipt . events . length ) . toBe ( 1 ) ;
297
373
const [ event ] = filterEvents ( receipt . events , CoreNodeEventType . ContractEvent ) ;
298
374
const printData = cvToValue < {
@@ -318,3 +394,13 @@ test('print events are emitted when claiming', () => {
318
394
expect ( printData . claimable ) . toBe ( constants . INITIAL_MINT_IMMEDIATE_AMOUNT ) ;
319
395
expect ( printData . recipient ) . toBe ( accounts . deployer . address ) ;
320
396
} ) ;
397
+
398
+ test ( 'claiming after waiting more than 1 month' , ( ) => {
399
+ mintInitial ( ) ;
400
+ simnet . mineEmptyBlocks ( months ( 1 ) ) ;
401
+ const receipt = txOk ( contract . claim ( ) , accounts . deployer . address ) ;
402
+ expect ( receipt . value ) . toBe (
403
+ constants . INITIAL_MINT_IMMEDIATE_AMOUNT +
404
+ constants . INITIAL_MINT_VESTING_AMOUNT / 24n ,
405
+ ) ;
406
+ } ) ;
0 commit comments