|
| 1 | +import * as assert from "assert"; |
| 2 | +import { getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate" |
| 3 | +import { devnet } from "@polkadot-api/descriptors" |
| 4 | +import { TypedApi } from "polkadot-api"; |
| 5 | +import { convertPublicKeyToSs58, convertH160ToSS58 } from "../src/address-utils" |
| 6 | +import { tao } from "../src/balance-math" |
| 7 | +import { ethers } from "ethers" |
| 8 | +import { generateRandomEthersWallet } from "../src/utils" |
| 9 | +import { convertH160ToPublicKey } from "../src/address-utils" |
| 10 | +import { |
| 11 | + forceSetBalanceToEthAddress, forceSetBalanceToSs58Address, addNewSubnetwork, burnedRegister, |
| 12 | + startCall, |
| 13 | +} from "../src/subtensor" |
| 14 | +import { ISTAKING_V2_ADDRESS, IStakingV2ABI } from "../src/contracts/staking" |
| 15 | + |
| 16 | +describe("Test staking precompile burn alpha", () => { |
| 17 | + // init eth part |
| 18 | + const wallet1 = generateRandomEthersWallet(); |
| 19 | + // init substrate part |
| 20 | + const hotkey = getRandomSubstrateKeypair(); |
| 21 | + const coldkey = getRandomSubstrateKeypair(); |
| 22 | + |
| 23 | + let api: TypedApi<typeof devnet> |
| 24 | + |
| 25 | + before(async () => { |
| 26 | + // init variables got from await and async |
| 27 | + api = await getDevnetApi() |
| 28 | + |
| 29 | + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey)) |
| 30 | + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey)) |
| 31 | + await forceSetBalanceToEthAddress(api, wallet1.address) |
| 32 | + |
| 33 | + let netuid = await addNewSubnetwork(api, hotkey, coldkey) |
| 34 | + await startCall(api, netuid, coldkey) |
| 35 | + |
| 36 | + console.log("test the case on subnet ", netuid) |
| 37 | + |
| 38 | + await burnedRegister(api, netuid, convertH160ToSS58(wallet1.address), coldkey) |
| 39 | + }) |
| 40 | + |
| 41 | + it("Can burn alpha after adding stake", async () => { |
| 42 | + let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1 |
| 43 | + |
| 44 | + // First add some stake |
| 45 | + let stakeBalance = tao(50) |
| 46 | + const contract = new ethers.Contract(ISTAKING_V2_ADDRESS, IStakingV2ABI, wallet1); |
| 47 | + const addStakeTx = await contract.addStake(hotkey.publicKey, stakeBalance.toString(), netuid) |
| 48 | + await addStakeTx.wait() |
| 49 | + |
| 50 | + // Get stake before burning |
| 51 | + const stakeBefore = BigInt(await contract.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet1.address), netuid)) |
| 52 | + |
| 53 | + console.log("Stake before burn:", stakeBefore) |
| 54 | + assert.ok(stakeBefore > BigInt(0), "Should have stake before burning") |
| 55 | + |
| 56 | + // Burn some alpha (burn 20 TAO worth) |
| 57 | + let burnAmount = tao(20) |
| 58 | + const burnTx = await contract.burnAlpha(hotkey.publicKey, burnAmount.toString(), netuid) |
| 59 | + await burnTx.wait() |
| 60 | + |
| 61 | + // Get stake after burning |
| 62 | + const stakeAfter = BigInt(await contract.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet1.address), netuid)) |
| 63 | + |
| 64 | + console.log("Stake after burn:", stakeAfter) |
| 65 | + |
| 66 | + // Verify that stake decreased by burn amount |
| 67 | + assert.ok(stakeAfter < stakeBefore, "Stake should decrease after burning") |
| 68 | + // assert.strictEqual(stakeBefore - stakeAfter, burnAmount, "Stake should decrease by exactly burn amount") |
| 69 | + }) |
| 70 | + |
| 71 | + it("Cannot burn more alpha than staked", async () => { |
| 72 | + let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1 |
| 73 | + |
| 74 | + // Get current stake |
| 75 | + const currentStake = await api.query.SubtensorModule.Alpha.getValue( |
| 76 | + convertPublicKeyToSs58(hotkey.publicKey), |
| 77 | + convertH160ToSS58(wallet1.address), |
| 78 | + netuid |
| 79 | + ) |
| 80 | + |
| 81 | + // Try to burn more than staked |
| 82 | + let burnAmount = currentStake + tao(10000) |
| 83 | + const contract = new ethers.Contract(ISTAKING_V2_ADDRESS, IStakingV2ABI, wallet1); |
| 84 | + |
| 85 | + try { |
| 86 | + const burnTx = await contract.burnAlpha(hotkey.publicKey, burnAmount.toString(), netuid) |
| 87 | + await burnTx.wait() |
| 88 | + assert.fail("Transaction should have failed - cannot burn more than staked"); |
| 89 | + } catch (error) { |
| 90 | + // Transaction failed as expected |
| 91 | + console.log("Correctly failed to burn more than staked amount") |
| 92 | + assert.ok(true, "Burning more than staked should fail"); |
| 93 | + } |
| 94 | + }) |
| 95 | + |
| 96 | + it("Cannot burn alpha from non-existent subnet", async () => { |
| 97 | + // wrong netuid |
| 98 | + let netuid = 12345; |
| 99 | + let burnAmount = tao(10) |
| 100 | + const contract = new ethers.Contract(ISTAKING_V2_ADDRESS, IStakingV2ABI, wallet1); |
| 101 | + |
| 102 | + try { |
| 103 | + const burnTx = await contract.burnAlpha(hotkey.publicKey, burnAmount.toString(), netuid) |
| 104 | + await burnTx.wait() |
| 105 | + assert.fail("Transaction should have failed - subnet doesn't exist"); |
| 106 | + } catch (error) { |
| 107 | + // Transaction failed as expected |
| 108 | + console.log("Correctly failed to burn from non-existent subnet") |
| 109 | + assert.ok(true, "Burning from non-existent subnet should fail"); |
| 110 | + } |
| 111 | + }) |
| 112 | + |
| 113 | + it("Cannot burn zero alpha", async () => { |
| 114 | + let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1 |
| 115 | + |
| 116 | + // First add some stake for this test |
| 117 | + let stakeBalance = tao(10) |
| 118 | + const contract = new ethers.Contract(ISTAKING_V2_ADDRESS, IStakingV2ABI, wallet1); |
| 119 | + const addStakeTx = await contract.addStake(hotkey.publicKey, stakeBalance.toString(), netuid) |
| 120 | + await addStakeTx.wait() |
| 121 | + |
| 122 | + // Try to burn zero amount |
| 123 | + let burnAmount = BigInt(0) |
| 124 | + |
| 125 | + try { |
| 126 | + const burnTx = await contract.burnAlpha(hotkey.publicKey, burnAmount.toString(), netuid) |
| 127 | + await burnTx.wait() |
| 128 | + assert.fail("Transaction should have failed - cannot burn zero amount"); |
| 129 | + } catch (error) { |
| 130 | + // Transaction failed as expected |
| 131 | + console.log("Correctly failed to burn zero amount") |
| 132 | + assert.ok(true, "Burning zero amount should fail"); |
| 133 | + } |
| 134 | + }) |
| 135 | +}) |
| 136 | + |
0 commit comments