From 633355605cdb23db36ad97f417a3d72648fc06fd Mon Sep 17 00:00:00 2001 From: Evgeny Svirsky Date: Thu, 23 Apr 2026 11:54:36 +0200 Subject: [PATCH 1/3] Use Address type instead of H256 for destination_address in the precompile --- contract-tests/src/contracts/staking.ts | 6 +++--- .../test/staking.precompile.approval.test.ts | 6 +++--- precompiles/src/solidity/stakingV2.abi | 6 +++--- precompiles/src/solidity/stakingV2.sol | 12 ++++++------ precompiles/src/staking.rs | 7 ++++--- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/contract-tests/src/contracts/staking.ts b/contract-tests/src/contracts/staking.ts index 418184fd9d..d25220ee1f 100644 --- a/contract-tests/src/contracts/staking.ts +++ b/contract-tests/src/contracts/staking.ts @@ -561,9 +561,9 @@ export const IStakingV2ABI = [ "type": "address" }, { - "internalType": "bytes32", - "name": "destination_coldkey", - "type": "bytes32" + "internalType": "address", + "name": "destination_address", + "type": "address" }, { "internalType": "bytes32", diff --git a/contract-tests/test/staking.precompile.approval.test.ts b/contract-tests/test/staking.precompile.approval.test.ts index 2717b90e5b..94161696cd 100644 --- a/contract-tests/test/staking.precompile.approval.test.ts +++ b/contract-tests/test/staking.precompile.approval.test.ts @@ -79,7 +79,7 @@ describe("Test approval in staking precompile", () => { const contract = new ethers.Contract(ISTAKING_V2_ADDRESS, IStakingV2ABI, wallet2); const tx = await contract.transferStakeFrom( wallet1.address, // source - convertH160ToPublicKey(wallet2.address), // distination + wallet2.address, // destination hotkey.publicKey, stakeNetuid, stakeNetuid, @@ -134,7 +134,7 @@ describe("Test approval in staking precompile", () => { // wallet2 transfer from wallet1 const tx = await contract.transferStakeFrom( wallet1.address, // source - convertH160ToPublicKey(wallet2.address), // destination + wallet2.address, // destination hotkey.publicKey, stakeNetuid, stakeNetuid, @@ -162,7 +162,7 @@ describe("Test approval in staking precompile", () => { const contract = new ethers.Contract(ISTAKING_V2_ADDRESS, IStakingV2ABI, wallet2); const tx = await contract.transferStakeFrom( wallet1.address, // source - convertH160ToPublicKey(wallet2.address), // distination + wallet2.address, // destination hotkey.publicKey, stakeNetuid, stakeNetuid, diff --git a/precompiles/src/solidity/stakingV2.abi b/precompiles/src/solidity/stakingV2.abi index 10ea3c7127..da91459d05 100644 --- a/precompiles/src/solidity/stakingV2.abi +++ b/precompiles/src/solidity/stakingV2.abi @@ -501,9 +501,9 @@ "type": "address" }, { - "internalType": "bytes32", - "name": "destination_coldkey", - "type": "bytes32" + "internalType": "address", + "name": "destination_address", + "type": "address" }, { "internalType": "bytes32", diff --git a/precompiles/src/solidity/stakingV2.sol b/precompiles/src/solidity/stakingV2.sol index f24e57b139..7fc114b19e 100644 --- a/precompiles/src/solidity/stakingV2.sol +++ b/precompiles/src/solidity/stakingV2.sol @@ -387,14 +387,14 @@ interface IStaking { * (spender) to spend at least the `amount` (allowance). The allowance towards that spender will be * decreased by this amount. * - * This function allows external accounts and contracts to transfer staked TAO to another coldkey, - * which effectively calls `transfer_stake` on the subtensor pallet with specified destination - * coldkey as a parameter being the hashed address mapping of H160 sender address to Substrate ss58 - * address as implemented in Frontier HashedAddressMapping: + * This function allows external accounts and contracts to transfer staked TAO to another EVM + * address, which effectively calls `transfer_stake` on the subtensor pallet. Both the source and + * destination EVM addresses are converted to their Substrate ss58 representation using Frontier + * HashedAddressMapping: * https://github.com/polkadot-evm/frontier/blob/2e219e17a526125da003e64ef22ec037917083fa/frame/evm/src/lib.rs#L739 * * @param source_address The source address (20 bytes). - * @param destination_coldkey The destination coldkey public key (32 bytes). + * @param destination_address The destination EVM address (20 bytes). * @param hotkey The hotkey public key (32 bytes). * @param origin_netuid The subnet to move stake from (uint256). * @param destination_netuid The subnet to move stake to (uint256). @@ -406,7 +406,7 @@ interface IStaking { */ function transferStakeFrom( address source_address, - bytes32 destination_coldkey, + address destination_address, bytes32 hotkey, uint256 origin_netuid, uint256 destination_netuid, diff --git a/precompiles/src/staking.rs b/precompiles/src/staking.rs index 3392de468e..f64f9ca319 100644 --- a/precompiles/src/staking.rs +++ b/precompiles/src/staking.rs @@ -634,11 +634,11 @@ where Ok(()) } - #[precompile::public("transferStakeFrom(address,bytes32,bytes32,uint256,uint256,uint256)")] + #[precompile::public("transferStakeFrom(address,address,bytes32,uint256,uint256,uint256)")] fn transfer_stake_from( handle: &mut impl PrecompileHandle, source_address: Address, - destination_coldkey: H256, + destination_address: Address, hotkey: H256, origin_netuid: U256, destination_netuid: U256, @@ -646,7 +646,8 @@ where ) -> EvmResult<()> { let spender = handle.context().caller; let source_address = source_address.0; - let destination_coldkey = R::AccountId::from(destination_coldkey.0); + let destination_coldkey = + ::AddressMapping::into_account_id(destination_address.0); let hotkey = R::AccountId::from(hotkey.0); let origin_netuid = try_u16_from_u256(origin_netuid)?; let destination_netuid = try_u16_from_u256(destination_netuid)?; From 4d057a77194af618dd207a9cb18c691ca9af60d0 Mon Sep 17 00:00:00 2001 From: Evgeny Svirsky Date: Thu, 23 Apr 2026 14:05:11 +0200 Subject: [PATCH 2/3] - snake -> camel --- contract-tests/src/contracts/staking.ts | 8 ++++---- precompiles/src/solidity/stakingV2.abi | 8 ++++---- precompiles/src/solidity/stakingV2.sol | 20 ++++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/contract-tests/src/contracts/staking.ts b/contract-tests/src/contracts/staking.ts index d25220ee1f..ad21b31be8 100644 --- a/contract-tests/src/contracts/staking.ts +++ b/contract-tests/src/contracts/staking.ts @@ -557,12 +557,12 @@ export const IStakingV2ABI = [ "inputs": [ { "internalType": "address", - "name": "source_address", + "name": "sourceAddress", "type": "address" }, { "internalType": "address", - "name": "destination_address", + "name": "destinationAddress", "type": "address" }, { @@ -572,12 +572,12 @@ export const IStakingV2ABI = [ }, { "internalType": "uint256", - "name": "origin_netuid", + "name": "originNetuid", "type": "uint256" }, { "internalType": "uint256", - "name": "destination_netuid", + "name": "destinationNetuid", "type": "uint256" }, { diff --git a/precompiles/src/solidity/stakingV2.abi b/precompiles/src/solidity/stakingV2.abi index da91459d05..69c1e339f2 100644 --- a/precompiles/src/solidity/stakingV2.abi +++ b/precompiles/src/solidity/stakingV2.abi @@ -497,12 +497,12 @@ "inputs": [ { "internalType": "address", - "name": "source_address", + "name": "sourceAddress", "type": "address" }, { "internalType": "address", - "name": "destination_address", + "name": "destinationAddress", "type": "address" }, { @@ -512,12 +512,12 @@ }, { "internalType": "uint256", - "name": "origin_netuid", + "name": "originNetuid", "type": "uint256" }, { "internalType": "uint256", - "name": "destination_netuid", + "name": "destinationNetuid", "type": "uint256" }, { diff --git a/precompiles/src/solidity/stakingV2.sol b/precompiles/src/solidity/stakingV2.sol index 7fc114b19e..7cc3c89a7c 100644 --- a/precompiles/src/solidity/stakingV2.sol +++ b/precompiles/src/solidity/stakingV2.sol @@ -382,8 +382,8 @@ interface IStaking { ) external; /** - * @dev Transfer a subtensor stake `amount` associated with the `source_address` to a different coldkey - * `destination_coldkey`. The `source_address` must have approved beforehand the transaction signer + * @dev Transfer a subtensor stake `amount` associated with the `sourceAddress` to a different + * destination address. The `sourceAddress` must have approved beforehand the transaction signer * (spender) to spend at least the `amount` (allowance). The allowance towards that spender will be * decreased by this amount. * @@ -393,11 +393,11 @@ interface IStaking { * HashedAddressMapping: * https://github.com/polkadot-evm/frontier/blob/2e219e17a526125da003e64ef22ec037917083fa/frame/evm/src/lib.rs#L739 * - * @param source_address The source address (20 bytes). - * @param destination_address The destination EVM address (20 bytes). + * @param sourceAddress The source address (20 bytes). + * @param destinationAddress The destination EVM address (20 bytes). * @param hotkey The hotkey public key (32 bytes). - * @param origin_netuid The subnet to move stake from (uint256). - * @param destination_netuid The subnet to move stake to (uint256). + * @param originNetuid The subnet to move stake from (uint256). + * @param destinationNetuid The subnet to move stake to (uint256). * @param amount The amount to move in rao. * * Requirements: @@ -405,11 +405,11 @@ interface IStaking { * that the stake is correctly attributed. */ function transferStakeFrom( - address source_address, - address destination_address, + address sourceAddress, + address destinationAddress, bytes32 hotkey, - uint256 origin_netuid, - uint256 destination_netuid, + uint256 originNetuid, + uint256 destinationNetuid, uint256 amount ) external; } From 336a5aa90050d0dd52c6759a8af008b3f02363db Mon Sep 17 00:00:00 2001 From: Evgeny Svirsky Date: Thu, 23 Apr 2026 17:25:59 +0200 Subject: [PATCH 3/3] - spec version bump --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index ca4cfa2255..c090237671 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -272,7 +272,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 399, + spec_version: 400, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,