@@ -47,6 +47,397 @@ describe("Test Alpha Precompile", () => {
4747 assert . ok ( alphaPrice >= BigInt ( 0 ) , "Alpha price should be non-negative" ) ;
4848 } ) ;
4949
50+ it ( "getMovingAlphaPrice returns valid moving price for subnet" , async ( ) => {
51+ const movingAlphaPrice = await publicClient . readContract ( {
52+ abi : IAlphaABI ,
53+ address : toViemAddress ( IALPHA_ADDRESS ) ,
54+ functionName : "getMovingAlphaPrice" ,
55+ args : [ subnetId ]
56+ } )
57+
58+ assert . ok ( movingAlphaPrice !== undefined , "Moving alpha price should be defined" ) ;
59+ assert . ok ( typeof movingAlphaPrice === 'bigint' , "Moving alpha price should be a bigint" ) ;
60+ assert . ok ( movingAlphaPrice >= BigInt ( 0 ) , "Moving alpha price should be non-negative" ) ;
61+ } ) ;
62+
63+ it ( "alpha prices are consistent for same subnet" , async ( ) => {
64+ const alphaPrice = await publicClient . readContract ( {
65+ abi : IAlphaABI ,
66+ address : toViemAddress ( IALPHA_ADDRESS ) ,
67+ functionName : "getAlphaPrice" ,
68+ args : [ subnetId ]
69+ } )
70+
71+ const movingAlphaPrice = await publicClient . readContract ( {
72+ abi : IAlphaABI ,
73+ address : toViemAddress ( IALPHA_ADDRESS ) ,
74+ functionName : "getMovingAlphaPrice" ,
75+ args : [ subnetId ]
76+ } )
77+
78+ // Both should be defined and valid
79+ assert . ok ( alphaPrice !== undefined && movingAlphaPrice !== undefined ) ;
80+ } ) ;
81+
82+ it ( "Tao in / Alpha in / Alpha out are consistent for same subnet" , async ( ) => {
83+ const taoInEmission = await publicClient . readContract ( {
84+ abi : IAlphaABI ,
85+ address : toViemAddress ( IALPHA_ADDRESS ) ,
86+ functionName : "getTaoInEmission" ,
87+ args : [ subnetId ]
88+ } )
89+
90+ const alphaInEmission = await publicClient . readContract ( {
91+ abi : IAlphaABI ,
92+ address : toViemAddress ( IALPHA_ADDRESS ) ,
93+ functionName : "getAlphaInEmission" ,
94+ args : [ subnetId ]
95+ } )
96+
97+ const alphaOutEmission = await publicClient . readContract ( {
98+ abi : IAlphaABI ,
99+ address : toViemAddress ( IALPHA_ADDRESS ) ,
100+ functionName : "getAlphaOutEmission" ,
101+ args : [ subnetId ]
102+ } )
103+
104+ // all should be defined and valid
105+ assert . ok ( taoInEmission !== undefined && alphaInEmission !== undefined && alphaOutEmission !== undefined ) ;
106+ } ) ;
107+
108+ it ( "getSumAlphaPrice returns valid sum of alpha prices" , async ( ) => {
109+ const sumAlphaPrice = await publicClient . readContract ( {
110+ abi : IAlphaABI ,
111+ address : toViemAddress ( IALPHA_ADDRESS ) ,
112+ functionName : "getSumAlphaPrice" ,
113+ args : [ ]
114+ } )
115+
116+ assert . ok ( sumAlphaPrice !== undefined , "Sum alpha price should be defined" ) ;
117+ } )
118+ } ) ;
119+
120+ describe ( "Pool Data Functions" , ( ) => {
121+ it ( "getTaoInPool returns valid TAO amount" , async ( ) => {
122+ const taoInPool = await publicClient . readContract ( {
123+ abi : IAlphaABI ,
124+ address : toViemAddress ( IALPHA_ADDRESS ) ,
125+ functionName : "getTaoInPool" ,
126+ args : [ subnetId ]
127+ } )
128+
129+ assert . ok ( taoInPool !== undefined , "TAO in pool should be defined" ) ;
130+ assert . ok ( typeof taoInPool === 'bigint' , "TAO in pool should be a bigint" ) ;
131+ assert . ok ( taoInPool >= BigInt ( 0 ) , "TAO in pool should be non-negative" ) ;
132+ } ) ;
50133
134+ it ( "getAlphaInPool returns valid Alpha amount" , async ( ) => {
135+ const alphaInPool = await publicClient . readContract ( {
136+ abi : IAlphaABI ,
137+ address : toViemAddress ( IALPHA_ADDRESS ) ,
138+ functionName : "getAlphaInPool" ,
139+ args : [ subnetId ]
140+ } )
141+
142+ assert . ok ( alphaInPool !== undefined , "Alpha in pool should be defined" ) ;
143+ assert . ok ( typeof alphaInPool === 'bigint' , "Alpha in pool should be a bigint" ) ;
144+ assert . ok ( alphaInPool >= BigInt ( 0 ) , "Alpha in pool should be non-negative" ) ;
145+ } ) ;
146+
147+ it ( "getAlphaOutPool returns valid Alpha out amount" , async ( ) => {
148+ const alphaOutPool = await publicClient . readContract ( {
149+ abi : IAlphaABI ,
150+ address : toViemAddress ( IALPHA_ADDRESS ) ,
151+ functionName : "getAlphaOutPool" ,
152+ args : [ subnetId ]
153+ } )
154+
155+ assert . ok ( alphaOutPool !== undefined , "Alpha out pool should be defined" ) ;
156+ assert . ok ( typeof alphaOutPool === 'bigint' , "Alpha out pool should be a bigint" ) ;
157+ assert . ok ( alphaOutPool >= BigInt ( 0 ) , "Alpha out pool should be non-negative" ) ;
158+ } ) ;
159+
160+ it ( "getAlphaIssuance returns valid issuance amount" , async ( ) => {
161+ const alphaIssuance = await publicClient . readContract ( {
162+ abi : IAlphaABI ,
163+ address : toViemAddress ( IALPHA_ADDRESS ) ,
164+ functionName : "getAlphaIssuance" ,
165+ args : [ subnetId ]
166+ } )
167+
168+ assert . ok ( alphaIssuance !== undefined , "Alpha issuance should be defined" ) ;
169+ assert . ok ( typeof alphaIssuance === 'bigint' , "Alpha issuance should be a bigint" ) ;
170+ assert . ok ( alphaIssuance >= BigInt ( 0 ) , "Alpha issuance should be non-negative" ) ;
171+ } ) ;
172+
173+ it ( "getCKBurn returns valid CK burn rate" , async ( ) => {
174+ const ckBurn = await publicClient . readContract ( {
175+ abi : IAlphaABI ,
176+ address : toViemAddress ( IALPHA_ADDRESS ) ,
177+ functionName : "getCKBurn" ,
178+ args : [ ]
179+ } )
180+
181+ const ckBurnOnChain = await api . query . SubtensorModule . CKBurn . getValue ( )
182+
183+ assert . strictEqual ( ckBurn , ckBurnOnChain , "CK burn should match on chain" ) ;
184+ assert . ok ( ckBurn !== undefined , "CK burn should be defined" ) ;
185+ const ckBurnPercentage = BigInt ( ckBurn ) * BigInt ( 100 ) / BigInt ( 2 ** 64 - 1 )
186+ assert . ok ( ckBurnPercentage >= BigInt ( 0 ) , "CK burn percentage should be non-negative" ) ;
187+ assert . ok ( ckBurnPercentage <= BigInt ( 100 ) , "CK burn percentage should be less than or equal to 100" ) ;
188+ assert . ok ( typeof ckBurn === 'bigint' , "CK burn should be a bigint" ) ;
189+ } ) ;
190+ } ) ;
191+
192+ describe ( "Global Functions" , ( ) => {
193+ it ( "getTaoWeight returns valid TAO weight" , async ( ) => {
194+ const taoWeight = await publicClient . readContract ( {
195+ abi : IAlphaABI ,
196+ address : toViemAddress ( IALPHA_ADDRESS ) ,
197+ functionName : "getTaoWeight" ,
198+ args : [ ]
199+ } )
200+
201+ assert . ok ( taoWeight !== undefined , "TAO weight should be defined" ) ;
202+ assert . ok ( typeof taoWeight === 'bigint' , "TAO weight should be a bigint" ) ;
203+ assert . ok ( taoWeight >= BigInt ( 0 ) , "TAO weight should be non-negative" ) ;
204+ } ) ;
205+
206+ it ( "getRootNetuid returns correct root netuid" , async ( ) => {
207+ const rootNetuid = await publicClient . readContract ( {
208+ abi : IAlphaABI ,
209+ address : toViemAddress ( IALPHA_ADDRESS ) ,
210+ functionName : "getRootNetuid" ,
211+ args : [ ]
212+ } )
213+
214+ assert . ok ( rootNetuid !== undefined , "Root netuid should be defined" ) ;
215+ assert . ok ( typeof rootNetuid === 'number' , "Root netuid should be a number" ) ;
216+ assert . strictEqual ( rootNetuid , 0 , "Root netuid should be 0" ) ;
217+ } ) ;
218+ } ) ;
219+
220+ describe ( "Swap Simulation Functions" , ( ) => {
221+ it ( "simSwapTaoForAlpha returns valid simulation" , async ( ) => {
222+ const taoAmount = BigInt ( 1000000000 ) ; // 1 TAO in RAO
223+ const simulatedAlpha = await publicClient . readContract ( {
224+ abi : IAlphaABI ,
225+ address : toViemAddress ( IALPHA_ADDRESS ) ,
226+ functionName : "simSwapTaoForAlpha" ,
227+ args : [ subnetId , taoAmount ]
228+ } )
229+
230+ assert . ok ( simulatedAlpha !== undefined , "Simulated alpha should be defined" ) ;
231+ assert . ok ( typeof simulatedAlpha === 'bigint' , "Simulated alpha should be a bigint" ) ;
232+ assert . ok ( simulatedAlpha >= BigInt ( 0 ) , "Simulated alpha should be non-negative" ) ;
233+ } ) ;
234+
235+ it ( "simSwapAlphaForTao returns valid simulation" , async ( ) => {
236+ const alphaAmount = BigInt ( 1000000000 ) ; // 1 Alpha
237+ const simulatedTao = await publicClient . readContract ( {
238+ abi : IAlphaABI ,
239+ address : toViemAddress ( IALPHA_ADDRESS ) ,
240+ functionName : "simSwapAlphaForTao" ,
241+ args : [ subnetId , alphaAmount ]
242+ } )
243+
244+ assert . ok ( simulatedTao !== undefined , "Simulated tao should be defined" ) ;
245+ assert . ok ( typeof simulatedTao === 'bigint' , "Simulated tao should be a bigint" ) ;
246+ assert . ok ( simulatedTao >= BigInt ( 0 ) , "Simulated tao should be non-negative" ) ;
247+ } ) ;
248+
249+ it ( "swap simulations handle zero amounts" , async ( ) => {
250+ const zeroTaoForAlpha = await publicClient . readContract ( {
251+ abi : IAlphaABI ,
252+ address : toViemAddress ( IALPHA_ADDRESS ) ,
253+ functionName : "simSwapTaoForAlpha" ,
254+ args : [ subnetId , BigInt ( 0 ) ]
255+ } )
256+
257+ const zeroAlphaForTao = await publicClient . readContract ( {
258+ abi : IAlphaABI ,
259+ address : toViemAddress ( IALPHA_ADDRESS ) ,
260+ functionName : "simSwapAlphaForTao" ,
261+ args : [ subnetId , BigInt ( 0 ) ]
262+ } )
263+
264+ assert . strictEqual ( zeroTaoForAlpha , BigInt ( 0 ) , "Zero TAO should result in zero Alpha" ) ;
265+ assert . strictEqual ( zeroAlphaForTao , BigInt ( 0 ) , "Zero Alpha should result in zero TAO" ) ;
266+ } ) ;
267+
268+ it ( "swap simulations are internally consistent" , async ( ) => {
269+ const taoAmount = BigInt ( 1000000000 ) ; // 1 TAO
270+
271+ // Simulate TAO -> Alpha
272+ const simulatedAlpha = await publicClient . readContract ( {
273+ abi : IAlphaABI ,
274+ address : toViemAddress ( IALPHA_ADDRESS ) ,
275+ functionName : "simSwapTaoForAlpha" ,
276+ args : [ subnetId , taoAmount ]
277+ } )
278+
279+ // If we got alpha, simulate Alpha -> TAO
280+ if ( ( simulatedAlpha as bigint ) > BigInt ( 0 ) ) {
281+ const simulatedTao = await publicClient . readContract ( {
282+ abi : IAlphaABI ,
283+ address : toViemAddress ( IALPHA_ADDRESS ) ,
284+ functionName : "simSwapAlphaForTao" ,
285+ args : [ subnetId , simulatedAlpha ]
286+ } )
287+
288+ // Check if simulated values are reasonably close (allowing for rounding/fees)
289+ if ( ( simulatedTao as bigint ) > BigInt ( 0 ) ) {
290+ const ratio = Number ( taoAmount ) / Number ( simulatedTao ) ;
291+ assert . ok ( ratio >= 0.5 && ratio <= 2.0 , "Swap simulation should be within reasonable bounds" ) ;
292+ }
293+ }
294+ } ) ;
295+ } ) ;
296+
297+ describe ( "Subnet Configuration Functions" , ( ) => {
298+ it ( "getSubnetMechanism returns valid mechanism" , async ( ) => {
299+ const mechanism = await publicClient . readContract ( {
300+ abi : IAlphaABI ,
301+ address : toViemAddress ( IALPHA_ADDRESS ) ,
302+ functionName : "getSubnetMechanism" ,
303+ args : [ subnetId ]
304+ } )
305+
306+ assert . ok ( mechanism !== undefined , "Subnet mechanism should be defined" ) ;
307+ assert . ok ( typeof mechanism === 'number' , "Subnet mechanism should be a number" ) ;
308+ assert . ok ( mechanism >= 0 , "Subnet mechanism should be non-negative" ) ;
309+ } ) ;
310+
311+ it ( "getEMAPriceHalvingBlocks returns valid halving period" , async ( ) => {
312+ const halvingBlocks = await publicClient . readContract ( {
313+ abi : IAlphaABI ,
314+ address : toViemAddress ( IALPHA_ADDRESS ) ,
315+ functionName : "getEMAPriceHalvingBlocks" ,
316+ args : [ subnetId ]
317+ } )
318+
319+ assert . ok ( halvingBlocks !== undefined , "EMA price halving blocks should be defined" ) ;
320+ assert . ok ( typeof halvingBlocks === 'bigint' , "EMA halving blocks should be a bigint" ) ;
321+ assert . ok ( halvingBlocks >= BigInt ( 0 ) , "EMA halving blocks should be non-negative" ) ;
322+ } ) ;
323+
324+ it ( "getSubnetVolume returns valid volume data" , async ( ) => {
325+ const subnetVolume = await publicClient . readContract ( {
326+ abi : IAlphaABI ,
327+ address : toViemAddress ( IALPHA_ADDRESS ) ,
328+ functionName : "getSubnetVolume" ,
329+ args : [ subnetId ]
330+ } )
331+
332+ assert . ok ( subnetVolume !== undefined , "Subnet volume should be defined" ) ;
333+ assert . ok ( typeof subnetVolume === 'bigint' , "Subnet volume should be a bigint" ) ;
334+ assert . ok ( subnetVolume >= BigInt ( 0 ) , "Subnet volume should be non-negative" ) ;
335+ } ) ;
336+ } ) ;
337+
338+ describe ( "Data Consistency with Pallet" , ( ) => {
339+ it ( "precompile data matches pallet values" , async ( ) => {
340+ // Get TAO in pool from precompile
341+ const taoInPool = await publicClient . readContract ( {
342+ abi : IAlphaABI ,
343+ address : toViemAddress ( IALPHA_ADDRESS ) ,
344+ functionName : "getTaoInPool" ,
345+ args : [ subnetId ]
346+ } )
347+
348+ // Get TAO in pool directly from the pallet
349+ const taoInPoolFromPallet = await api . query . SubtensorModule . SubnetTAO . getValue ( subnetId ) ;
350+
351+ // Compare values
352+ assert . strictEqual ( taoInPool as bigint , taoInPoolFromPallet , "TAO in pool values should match" ) ;
353+
354+ // Get Alpha in pool from precompile
355+ const alphaInPool = await publicClient . readContract ( {
356+ abi : IAlphaABI ,
357+ address : toViemAddress ( IALPHA_ADDRESS ) ,
358+ functionName : "getAlphaInPool" ,
359+ args : [ subnetId ]
360+ } )
361+
362+ // Get Alpha in pool directly from the pallet
363+ const alphaInPoolFromPallet = await api . query . SubtensorModule . SubnetAlphaIn . getValue ( subnetId ) ;
364+
365+ // Compare values
366+ assert . strictEqual ( alphaInPool as bigint , alphaInPoolFromPallet , "Alpha in pool values should match" ) ;
367+
368+ // Get Alpha out pool from precompile
369+ const alphaOutPool = await publicClient . readContract ( {
370+ abi : IAlphaABI ,
371+ address : toViemAddress ( IALPHA_ADDRESS ) ,
372+ functionName : "getAlphaOutPool" ,
373+ args : [ subnetId ]
374+ } )
375+
376+ // Get Alpha out pool directly from the pallet
377+ const alphaOutPoolFromPallet = await api . query . SubtensorModule . SubnetAlphaOut . getValue ( subnetId ) ;
378+
379+ // Compare values
380+ assert . strictEqual ( alphaOutPool as bigint , alphaOutPoolFromPallet , "Alpha out pool values should match" ) ;
381+ } ) ;
382+
383+ it ( "subnet volume data is consistent" , async ( ) => {
384+ const subnetVolume = await publicClient . readContract ( {
385+ abi : IAlphaABI ,
386+ address : toViemAddress ( IALPHA_ADDRESS ) ,
387+ functionName : "getSubnetVolume" ,
388+ args : [ subnetId ]
389+ } )
390+
391+ const subnetVolumeFromPallet = await api . query . SubtensorModule . SubnetVolume . getValue ( subnetId ) ;
392+
393+ assert . strictEqual ( subnetVolume as bigint , subnetVolumeFromPallet , "Subnet volume values should match" ) ;
394+ } ) ;
395+ } ) ;
396+
397+ describe ( "Edge Cases and Error Handling" , ( ) => {
398+ it ( "handles non-existent subnet gracefully" , async ( ) => {
399+ const nonExistentSubnet = 9999 ;
400+
401+ // These should not throw but return default values
402+ const alphaPrice = await publicClient . readContract ( {
403+ abi : IAlphaABI ,
404+ address : toViemAddress ( IALPHA_ADDRESS ) ,
405+ functionName : "getAlphaPrice" ,
406+ args : [ nonExistentSubnet ]
407+ } )
408+
409+ const taoInPool = await publicClient . readContract ( {
410+ abi : IAlphaABI ,
411+ address : toViemAddress ( IALPHA_ADDRESS ) ,
412+ functionName : "getTaoInPool" ,
413+ args : [ nonExistentSubnet ]
414+ } )
415+
416+ // Should return default values, not throw
417+ assert . ok ( alphaPrice !== undefined , "Should handle non-existent subnet gracefully" ) ;
418+ assert . ok ( taoInPool !== undefined , "Should handle non-existent subnet gracefully" ) ;
419+ } ) ;
420+
421+ it ( "simulation functions handle large amounts" , async ( ) => {
422+ const largeAmount = BigInt ( "1000000000000000000" ) ; // Very large amount
423+
424+ const simulatedAlpha = await publicClient . readContract ( {
425+ abi : IAlphaABI ,
426+ address : toViemAddress ( IALPHA_ADDRESS ) ,
427+ functionName : "simSwapTaoForAlpha" ,
428+ args : [ subnetId , largeAmount ]
429+ } )
430+
431+ const simulatedTao = await publicClient . readContract ( {
432+ abi : IAlphaABI ,
433+ address : toViemAddress ( IALPHA_ADDRESS ) ,
434+ functionName : "simSwapAlphaForTao" ,
435+ args : [ subnetId , largeAmount ]
436+ } )
437+
438+ // Should handle large amounts without throwing
439+ assert . ok ( simulatedAlpha !== undefined , "Should handle large TAO amounts" ) ;
440+ assert . ok ( simulatedTao !== undefined , "Should handle large Alpha amounts" ) ;
441+ } ) ;
51442 } ) ;
52443} ) ;
0 commit comments