From 67db3dd0de08b1d51928281c22a89404a2f04a7c Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 14:29:20 +0900 Subject: [PATCH 01/20] chore: checked sub and add for all remaining pallet ops --- client/rpc/trace/src/lib.rs | 5 ++- .../src/functions/delegate.rs | 36 ++++++++++++++----- .../src/types/delegator.rs | 2 +- .../src/types/operator.rs | 4 +-- .../tangle-lst/src/tests/withdraw_unbonded.rs | 2 +- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/client/rpc/trace/src/lib.rs b/client/rpc/trace/src/lib.rs index 72c564dfd..2cca9c070 100644 --- a/client/rpc/trace/src/lib.rs +++ b/client/rpc/trace/src/lib.rs @@ -720,7 +720,10 @@ where // last batch containing it. let mut remove = false; if let Some(block_cache) = self.cached_blocks.get_mut(&block) { - block_cache.active_batch_count -= 1; + block_cache.active_batch_count = block_cache + .active_batch_count + .checked_sub(1) + .expect("active_batch_count underflow"); if block_cache.active_batch_count == 0 { remove = true; diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 36c05f8c3..1ec047a02 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -70,7 +70,8 @@ impl Pallet { .iter_mut() .find(|d| d.operator == operator && d.asset_id == asset_id) { - delegation.amount += amount; + delegation.amount = + delegation.amount.checked_add(&amount).ok_or(Error::::OverflowRisk)?; } else { // Create the new delegation let new_delegation = BondInfoDelegator { @@ -108,7 +109,10 @@ impl Pallet { if let Some(existing_delegation) = delegations.iter_mut().find(|d| d.delegator == who && d.asset_id == asset_id) { - existing_delegation.amount += amount; + existing_delegation.amount = existing_delegation + .amount + .checked_add(&amount) + .ok_or(Error::::OverflowRisk)?; } else { delegations .try_push(delegation) @@ -164,7 +168,8 @@ impl Pallet { let delegation = &mut metadata.delegations[delegation_index]; ensure!(delegation.amount >= amount, Error::::InsufficientBalance); - delegation.amount -= amount; + delegation.amount = + delegation.amount.checked_sub(&amount).ok_or(Error::::InsufficientBalance)?; // Create the unstake request let current_round = Self::current_round(); @@ -202,12 +207,18 @@ impl Pallet { // Reduce the amount in the operator's delegation ensure!(operator_delegation.amount >= amount, Error::::InsufficientBalance); - operator_delegation.amount -= amount; + operator_delegation.amount = operator_delegation + .amount + .checked_sub(&amount) + .ok_or(Error::::InsufficientBalance)?; // Remove the delegation if the remaining amount is zero if operator_delegation.amount.is_zero() { operator_metadata.delegations.remove(operator_delegation_index); - operator_metadata.delegation_count -= 1; + operator_metadata.delegation_count = operator_metadata + .delegation_count + .checked_sub(&1) + .ok_or(Error::::InsufficientBalance)?; } Ok(()) @@ -315,14 +326,20 @@ impl Pallet { .iter_mut() .find(|d| d.asset_id == asset_id && d.delegator == who.clone()) { - delegation.amount += amount; + delegation.amount = delegation + .amount + .checked_add(&amount) + .ok_or(Error::::OverflowRisk)?; } else { delegations .try_push(DelegatorBond { delegator: who.clone(), amount, asset_id }) .map_err(|_| Error::::MaxDelegationsExceeded)?; // Increase the delegation count only when a new delegation is added - operator_metadata.delegation_count += 1; + operator_metadata.delegation_count = operator_metadata + .delegation_count + .checked_add(1) + .ok_or(Error::::OverflowRisk)?; } operator_metadata.delegations = delegations; @@ -337,7 +354,10 @@ impl Pallet { if let Some(delegation) = delegations.iter_mut().find(|d| { d.operator == unstake_request.operator && d.asset_id == unstake_request.asset_id }) { - delegation.amount += unstake_request.amount; + delegation.amount = delegation + .amount + .checked_add(&unstake_request.amount) + .ok_or(Error::::OverflowRisk)?; } else { // Create a new delegation delegations diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 23ef2bc41..19c1d324f 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -192,7 +192,7 @@ impl< let mut total = Balance::default(); for stake in &self.delegations { if stake.asset_id == asset_id { - total += stake.amount.clone(); + total = total.checked_add(&stake.amount).unwrap_or_else(|| total); } } total diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index e0e7ca270..a92171ae9 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -41,7 +41,7 @@ where let mut total_stake = Balance::default(); for stake in &self.delegations { if stake.asset_id == asset_id { - total_stake += stake.amount; + total_stake = total_stake.checked_add(&stake.amount).unwrap_or(total_stake); } } total_stake @@ -53,7 +53,7 @@ where for stake in &self.delegations { let entry = stake_by_asset.entry(stake.asset_id).or_default(); - *entry += stake.amount; + *entry = entry.checked_add(&stake.amount).unwrap_or(*entry); } stake_by_asset.into_iter().collect() diff --git a/pallets/tangle-lst/src/tests/withdraw_unbonded.rs b/pallets/tangle-lst/src/tests/withdraw_unbonded.rs index 86001457a..1b9577da1 100644 --- a/pallets/tangle-lst/src/tests/withdraw_unbonded.rs +++ b/pallets/tangle-lst/src/tests/withdraw_unbonded.rs @@ -69,7 +69,7 @@ fn withdraw_unbonded_works_against_slashed_no_era_sub_pool() { SubPoolsStorage::::insert(1, sub_pools); // Adjust the TVL for this non-api usage (direct sub-pool modification) - TotalValueLocked::::mutate(|x| *x -= 295); + TotalValueLocked::::mutate(|x| *x = x.saturating_sub(295)); // Update the equivalent of the unbonding chunks for the `StakingMock` let mut x = UnbondingBalanceMap::get(); From c5c96501b78b160caab6f761bc95acdd8d0e7485 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 14:39:44 +0900 Subject: [PATCH 02/20] chore: HAL-011 --- client/evm-tracing/src/types/single.rs | 1 - precompiles/balances-erc20/src/lib.rs | 3 ++- precompiles/pallet-democracy/DemocracyInterface.sol | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/client/evm-tracing/src/types/single.rs b/client/evm-tracing/src/types/single.rs index 54a8b9d7d..7ac680a6f 100644 --- a/client/evm-tracing/src/types/single.rs +++ b/client/evm-tracing/src/types/single.rs @@ -68,7 +68,6 @@ pub struct RawStepLog { #[serde(serialize_with = "u256_serialize")] pub depth: U256, - //error: TODO #[serde(serialize_with = "u256_serialize")] pub gas: U256, diff --git a/precompiles/balances-erc20/src/lib.rs b/precompiles/balances-erc20/src/lib.rs index aa3a6b4f5..6688d7300 100644 --- a/precompiles/balances-erc20/src/lib.rs +++ b/precompiles/balances-erc20/src/lib.rs @@ -61,7 +61,8 @@ pub const SELECTOR_LOG_DEPOSIT: [u8; 32] = keccak256!("Deposit(address,uint256)" pub const SELECTOR_LOG_WITHDRAWAL: [u8; 32] = keccak256!("Withdrawal(address,uint256)"); /// Solidity selector of the TransferNative log, which is the Keccak of the Log signature. -pub const SELECTOR_LOG_TRANSFER_NATIVE: [u8; 32] = keccak256!("TransferNative(bytes32,uint256)"); +pub const SELECTOR_LOG_TRANSFER_NATIVE: [u8; 32] = + keccak256!("TransferNative(address,bytes32,uint256)"); /// Associates pallet Instance to a prefix used for the Approves storage. /// This trait is implemented for () and the 16 substrate Instance. diff --git a/precompiles/pallet-democracy/DemocracyInterface.sol b/precompiles/pallet-democracy/DemocracyInterface.sol index 810575ee4..bb6b9dfe3 100644 --- a/precompiles/pallet-democracy/DemocracyInterface.sol +++ b/precompiles/pallet-democracy/DemocracyInterface.sol @@ -111,8 +111,6 @@ interface Democracy { /// This is necessary for calculating the weight of the call. function second(uint256 propIndex, uint256 secondsUpperBound) external; - //TODO should we have an alternative `simpleSecond` where the upper bound is read from storage? - /// Vote in a referendum. /// @custom:selector 6cd18b0d /// From 197e11111c789bb55b7c67d53e122b921ce9bbfb Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 14:42:24 +0900 Subject: [PATCH 03/20] chore: HAL-012 --- precompiles/balances-erc20/ERC20.sol | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/precompiles/balances-erc20/ERC20.sol b/precompiles/balances-erc20/ERC20.sol index 07ee6a3ab..d49ea5db0 100644 --- a/precompiles/balances-erc20/ERC20.sol +++ b/precompiles/balances-erc20/ERC20.sol @@ -88,6 +88,13 @@ interface IERC20 { /// @param value uint256 The amount of tokens transfered. event Transfer(address indexed from, address indexed to, uint256 value); + /// @dev Event emited when a native transfer has been performed. + /// @custom:selector 252d1c824457d58ee034ca5279c879eea06e3cf5f3d0df73d9f6939f9d081c8c + /// @param from address The address sending the tokens + /// @param to bytes32 The accountId32 receiving the tokens. + /// @param value uint256 The amount of tokens transfered. + event TransferNative(address indexed from, bytes32 indexed to, uint256 value); + /// @dev Event emited when an approval has been registered. /// @custom:selector 8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 /// @param owner address Owner of the tokens. From fd23236b7ff59d6740f458d2d69d50bf6d57f565 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 14:49:28 +0900 Subject: [PATCH 04/20] chore: HAL-016 --- .../evm-tracing/src/formatters/blockscout.rs | 11 +++++----- .../evm-tracing/src/formatters/call_tracer.rs | 11 +++++----- client/evm-tracing/src/formatters/mod.rs | 11 +++++----- client/evm-tracing/src/formatters/raw.rs | 11 +++++----- .../src/formatters/trace_filter.rs | 11 +++++----- client/evm-tracing/src/lib.rs | 11 +++++----- client/evm-tracing/src/listeners/call_list.rs | 11 +++++----- client/evm-tracing/src/listeners/mod.rs | 11 +++++----- client/evm-tracing/src/listeners/raw.rs | 11 +++++----- client/evm-tracing/src/types/block.rs | 11 +++++----- client/evm-tracing/src/types/mod.rs | 11 +++++----- client/evm-tracing/src/types/serialization.rs | 11 +++++----- client/evm-tracing/src/types/single.rs | 11 +++++----- client/rpc-core/debug/src/lib.rs | 11 +++++----- client/rpc-core/trace/src/lib.rs | 11 +++++----- client/rpc-core/txpool/src/lib.rs | 11 +++++----- client/rpc-core/txpool/src/types/content.rs | 11 +++++----- client/rpc-core/txpool/src/types/inspect.rs | 11 +++++----- client/rpc-core/txpool/src/types/mod.rs | 11 +++++----- client/rpc-core/types/src/lib.rs | 11 +++++----- client/rpc/debug/README.md | 22 +++++++++---------- client/rpc/debug/src/lib.rs | 11 +++++----- client/rpc/trace/src/lib.rs | 11 +++++----- client/rpc/txpool/src/lib.rs | 11 +++++----- evm-tracer/src/lib.rs | 11 +++++----- node/src/rpc/tracing.rs | 11 +++++----- precompiles/assets-erc20/src/lib.rs | 4 ++-- precompiles/balances-erc20/Permit.sol | 3 ++- precompiles/balances-erc20/src/eip2612.rs | 11 +++++----- precompiles/balances-erc20/src/lib.rs | 11 +++++----- precompiles/balances-erc20/src/mock.rs | 11 +++++----- precompiles/balances-erc20/src/tests.rs | 11 +++++----- precompiles/batch/Batch.sol | 3 ++- precompiles/call-permit/CallPermit.sol | 3 ++- .../pallet-democracy/DemocracyInterface.sol | 3 ++- .../PrecompileRegistry.sol | 3 ++- precompiles/preimage/Preimage.sol | 3 ++- precompiles/proxy/Proxy.sol | 3 ++- primitives/ext/src/lib.rs | 17 +++++++------- primitives/rpc/debug/src/lib.rs | 11 +++++----- primitives/rpc/evm-tracing-events/src/evm.rs | 11 +++++----- .../rpc/evm-tracing-events/src/gasometer.rs | 11 +++++----- primitives/rpc/evm-tracing-events/src/lib.rs | 11 +++++----- .../rpc/evm-tracing-events/src/runtime.rs | 11 +++++----- primitives/rpc/txpool/src/lib.rs | 11 +++++----- 45 files changed, 245 insertions(+), 204 deletions(-) diff --git a/client/evm-tracing/src/formatters/blockscout.rs b/client/evm-tracing/src/formatters/blockscout.rs index 61b8033e2..214e47da5 100644 --- a/client/evm-tracing/src/formatters/blockscout.rs +++ b/client/evm-tracing/src/formatters/blockscout.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use crate::{ listeners::call_list::Listener, diff --git a/client/evm-tracing/src/formatters/call_tracer.rs b/client/evm-tracing/src/formatters/call_tracer.rs index 6b2d7ae4a..66e577343 100644 --- a/client/evm-tracing/src/formatters/call_tracer.rs +++ b/client/evm-tracing/src/formatters/call_tracer.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . #[allow(clippy::all)] use super::blockscout::BlockscoutCallInner; use crate::types::{ diff --git a/client/evm-tracing/src/formatters/mod.rs b/client/evm-tracing/src/formatters/mod.rs index 5af0bfb63..8237a0fc9 100644 --- a/client/evm-tracing/src/formatters/mod.rs +++ b/client/evm-tracing/src/formatters/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . pub mod blockscout; pub mod call_tracer; pub mod raw; diff --git a/client/evm-tracing/src/formatters/raw.rs b/client/evm-tracing/src/formatters/raw.rs index 30e352427..adf00c617 100644 --- a/client/evm-tracing/src/formatters/raw.rs +++ b/client/evm-tracing/src/formatters/raw.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use crate::{listeners::raw::Listener, types::single::TransactionTrace}; diff --git a/client/evm-tracing/src/formatters/trace_filter.rs b/client/evm-tracing/src/formatters/trace_filter.rs index 9bb032107..4111ab1ea 100644 --- a/client/evm-tracing/src/formatters/trace_filter.rs +++ b/client/evm-tracing/src/formatters/trace_filter.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use super::blockscout::BlockscoutCallInner as CallInner; use crate::{ diff --git a/client/evm-tracing/src/lib.rs b/client/evm-tracing/src/lib.rs index 12a21b36c..ef97dcd60 100644 --- a/client/evm-tracing/src/lib.rs +++ b/client/evm-tracing/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! This crate contains the client-side part that interacts with our "v2" tracing design. #![allow(clippy::all)] diff --git a/client/evm-tracing/src/listeners/call_list.rs b/client/evm-tracing/src/listeners/call_list.rs index 9da8a66a0..d0561e409 100644 --- a/client/evm-tracing/src/listeners/call_list.rs +++ b/client/evm-tracing/src/listeners/call_list.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use crate::{ formatters::blockscout::{BlockscoutCall as Call, BlockscoutCallInner as CallInner}, diff --git a/client/evm-tracing/src/listeners/mod.rs b/client/evm-tracing/src/listeners/mod.rs index 5049d5f58..245e06580 100644 --- a/client/evm-tracing/src/listeners/mod.rs +++ b/client/evm-tracing/src/listeners/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . pub mod call_list; pub mod raw; diff --git a/client/evm-tracing/src/listeners/raw.rs b/client/evm-tracing/src/listeners/raw.rs index 483ea0a3d..3a1b7408a 100644 --- a/client/evm-tracing/src/listeners/raw.rs +++ b/client/evm-tracing/src/listeners/raw.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use ethereum_types::{H160, H256}; use std::{collections::btree_map::BTreeMap, vec, vec::Vec}; diff --git a/client/evm-tracing/src/types/block.rs b/client/evm-tracing/src/types/block.rs index e00b5e15a..b75608715 100644 --- a/client/evm-tracing/src/types/block.rs +++ b/client/evm-tracing/src/types/block.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! Types for tracing all Ethereum transactions of a block. diff --git a/client/evm-tracing/src/types/mod.rs b/client/evm-tracing/src/types/mod.rs index b2989b9d5..2854ecdb3 100644 --- a/client/evm-tracing/src/types/mod.rs +++ b/client/evm-tracing/src/types/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! Runtime API allowing to debug/trace Ethereum #![allow(clippy::all)] diff --git a/client/evm-tracing/src/types/serialization.rs b/client/evm-tracing/src/types/serialization.rs index f786ffafd..0dcc8e896 100644 --- a/client/evm-tracing/src/types/serialization.rs +++ b/client/evm-tracing/src/types/serialization.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! Provide serialization functions for various types and formats. diff --git a/client/evm-tracing/src/types/single.rs b/client/evm-tracing/src/types/single.rs index 7ac680a6f..60c623c6d 100644 --- a/client/evm-tracing/src/types/single.rs +++ b/client/evm-tracing/src/types/single.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! Types for the tracing of a single Ethereum transaction. //! Structure from "raw" debug_trace and a "call list" matching diff --git a/client/rpc-core/debug/src/lib.rs b/client/rpc-core/debug/src/lib.rs index a2be4a438..c2e2772fa 100644 --- a/client/rpc-core/debug/src/lib.rs +++ b/client/rpc-core/debug/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use client_evm_tracing::types::single; use ethereum::AccessListItem; diff --git a/client/rpc-core/trace/src/lib.rs b/client/rpc-core/trace/src/lib.rs index ea770c45b..7224fe26c 100644 --- a/client/rpc-core/trace/src/lib.rs +++ b/client/rpc-core/trace/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use client_evm_tracing::types::block::TransactionTrace; use ethereum_types::H160; diff --git a/client/rpc-core/txpool/src/lib.rs b/client/rpc-core/txpool/src/lib.rs index 87d6dbe82..40ddb733c 100644 --- a/client/rpc-core/txpool/src/lib.rs +++ b/client/rpc-core/txpool/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use ethereum_types::U256; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; diff --git a/client/rpc-core/txpool/src/types/content.rs b/client/rpc-core/txpool/src/types/content.rs index ec98a00f4..31458ca48 100644 --- a/client/rpc-core/txpool/src/types/content.rs +++ b/client/rpc-core/txpool/src/types/content.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use crate::GetT; use ethereum::{TransactionAction, TransactionV2 as EthereumTransaction}; diff --git a/client/rpc-core/txpool/src/types/inspect.rs b/client/rpc-core/txpool/src/types/inspect.rs index 95e7240bc..53b94253a 100644 --- a/client/rpc-core/txpool/src/types/inspect.rs +++ b/client/rpc-core/txpool/src/types/inspect.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use crate::GetT; use ethereum::{TransactionAction, TransactionV2 as EthereumTransaction}; diff --git a/client/rpc-core/txpool/src/types/mod.rs b/client/rpc-core/txpool/src/types/mod.rs index 67c71b087..cf2f233e1 100644 --- a/client/rpc-core/txpool/src/types/mod.rs +++ b/client/rpc-core/txpool/src/types/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . mod content; mod inspect; diff --git a/client/rpc-core/types/src/lib.rs b/client/rpc-core/types/src/lib.rs index ae796f054..0c8800502 100644 --- a/client/rpc-core/types/src/lib.rs +++ b/client/rpc-core/types/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc.. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use ethereum_types::H256; use serde::{de::Error, Deserialize, Deserializer}; diff --git a/client/rpc/debug/README.md b/client/rpc/debug/README.md index d46462f26..bcf905146 100644 --- a/client/rpc/debug/README.md +++ b/client/rpc/debug/README.md @@ -1,19 +1,17 @@ A port crate of some of the tracing related rpc requests from the go-ethereum [debug namespace](https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-debug). Includes `debug_traceTransaction`, `debug_traceBlockByNumber` and `debug_traceBlockByHash`. -## How tracing works in Moonbeam +## How tracing works in Tangle Runtime wasms compiled with the `tracing` evm feature will emit events related to entering/exiting substates or opcode execution. This events are used by developers or indexer services to get a granular view on an evm transaction. -Tracing wasms for each moonbeam/river/base runtime versions live at `moonbeam-runtime-overrides` repository in github. +Tracing functionality in tangle makes heavy use of [environmental](https://docs.rs/environmental/latest/environmental/): -Tracing functionality in Moonbeam makes heavy use of [environmental](https://docs.rs/environmental/latest/environmental/): - -- The rpc request must create a runtime api instance to replay the transaction. The runtime api call is made `using` `environmental`. -- Once in the wasm, the target evm transaction is replayed by calling the evm also `using` `environmental`. -- This allows: - 1. Listen to new events from the evm in the moonbeam runtime wasm. - 2. Proxy those events to the client (through a host function), which is also listening for events from the runtime. -- This way we don't make use of (limited) wasm memory, and instead store the evm emitted events content in the client. +- The rpc request must create a runtime api instance to replay the transaction. The runtime api call is made `using` `environmental`. +- Once in the wasm, the target evm transaction is replayed by calling the evm also `using` `environmental`. +- This allows: + 1. Listen to new events from the evm in the tangle runtime wasm. + 2. Proxy those events to the client (through a host function), which is also listening for events from the runtime. +- This way we don't make use of (limited) wasm memory, and instead store the evm emitted events content in the client. Once the evm execution concludes, the runtime context exited and all events have been stored in the client memory, we support formatting the captured events in different ways that are convenient for the end-user, like raw format (opcode level tracing), callTracer (used as a default formatter by geth) or blockscout custom tracer. @@ -63,8 +61,8 @@ sp_api::decl_runtime_apis! { Substrate provides two macro attributes to do what we want: `api_version` and `changed_in`. -- `api_version`: is the current version of the Api. In our case we updated it to `#[api_version(2)]`. -- changed_in: is meant to describe for `decl_runtime_apis` macro past implementations of methods. In this case, we anotate our previous implementation with `#[changed_in(2)]`, telling the `decl_runtime_apis` macro that this is the implementation to use before version 2. In fact, this attribute will rename the method name for the trait in the client side to `METHOD_before_version_VERSION`, so `trace_transaction_before_version_2` in our example. +- `api_version`: is the current version of the Api. In our case we updated it to `#[api_version(2)]`. +- changed_in: is meant to describe for `decl_runtime_apis` macro past implementations of methods. In this case, we anotate our previous implementation with `#[changed_in(2)]`, telling the `decl_runtime_apis` macro that this is the implementation to use before version 2. In fact, this attribute will rename the method name for the trait in the client side to `METHOD_before_version_VERSION`, so `trace_transaction_before_version_2` in our example. The un-anotated method is considered the default implemetation, and holds the current `trace_transaction` signature, with the new header argument and the empty result. diff --git a/client/rpc/debug/src/lib.rs b/client/rpc/debug/src/lib.rs index 09b2b932c..9805a6174 100644 --- a/client/rpc/debug/src/lib.rs +++ b/client/rpc/debug/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use futures::StreamExt; use jsonrpsee::core::{async_trait, RpcResult}; pub use rpc_core_debug::{DebugServer, TraceCallParams, TraceParams}; diff --git a/client/rpc/trace/src/lib.rs b/client/rpc/trace/src/lib.rs index 2cca9c070..80f9cc754 100644 --- a/client/rpc/trace/src/lib.rs +++ b/client/rpc/trace/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! `trace_filter` RPC handler and its associated service task. //! The RPC handler rely on `CacheTask` which provides a future that must be run inside a tokio diff --git a/client/rpc/txpool/src/lib.rs b/client/rpc/txpool/src/lib.rs index 101050c5b..2bb48e3fc 100644 --- a/client/rpc/txpool/src/lib.rs +++ b/client/rpc/txpool/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use ethereum_types::{H160, H256, U256}; use fc_rpc::{internal_err, public_key}; diff --git a/evm-tracer/src/lib.rs b/evm-tracer/src/lib.rs index 6fa5766f7..b23b497b4 100644 --- a/evm-tracer/src/lib.rs +++ b/evm-tracer/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! Substrate EVM tracing. //! diff --git a/node/src/rpc/tracing.rs b/node/src/rpc/tracing.rs index 18514cae5..2ea205ce6 100644 --- a/node/src/rpc/tracing.rs +++ b/node/src/rpc/tracing.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use std::time::Duration; diff --git a/precompiles/assets-erc20/src/lib.rs b/precompiles/assets-erc20/src/lib.rs index 91a074166..3c032ed27 100644 --- a/precompiles/assets-erc20/src/lib.rs +++ b/precompiles/assets-erc20/src/lib.rs @@ -72,8 +72,8 @@ pub trait AddressToAssetId { /// The following distribution has been decided for the precompiles /// 0-1023: Ethereum Mainnet Precompiles -/// 1024-2047 Precompiles that are not in Ethereum Mainnet but are neither Moonbeam specific -/// 2048-4095 Moonbeam specific precompiles +/// 1024-2047 Precompiles that are not in Ethereum Mainnet but are neither Tangle specific +/// 2048-4095 Tangle specific precompiles /// Asset precompiles can only fall between /// 0xFFFFFFFF00000000000000000000000000000000 - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF /// The precompile for AssetId X, where X is a u128 (i.e.16 bytes), if 0XFFFFFFFF + Bytes(AssetId) diff --git a/precompiles/balances-erc20/Permit.sol b/precompiles/balances-erc20/Permit.sol index c71340685..c84055d5e 100644 --- a/precompiles/balances-erc20/Permit.sol +++ b/precompiles/balances-erc20/Permit.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.8.3; -/// @author The Moonbeam Team +/// @author Tangle Network +/// @author Originally built by Moonbeam Team /// @title Extension of the ERC20 interface that allows users to /// @dev Sign permit messages to interact with contracts without needing to /// make a first approve transaction. diff --git a/precompiles/balances-erc20/src/eip2612.rs b/precompiles/balances-erc20/src/eip2612.rs index beb46e754..4853a8a9c 100644 --- a/precompiles/balances-erc20/src/eip2612.rs +++ b/precompiles/balances-erc20/src/eip2612.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use super::*; use frame_support::{ diff --git a/precompiles/balances-erc20/src/lib.rs b/precompiles/balances-erc20/src/lib.rs index 6688d7300..360fc3ea3 100644 --- a/precompiles/balances-erc20/src/lib.rs +++ b/precompiles/balances-erc20/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! Precompile to interact with pallet_balances instances using the ERC20 interface standard. #![allow(clippy::all)] diff --git a/precompiles/balances-erc20/src/mock.rs b/precompiles/balances-erc20/src/mock.rs index fa5d1e4bd..fb6e79d02 100644 --- a/precompiles/balances-erc20/src/mock.rs +++ b/precompiles/balances-erc20/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! Testing utilities. diff --git a/precompiles/balances-erc20/src/tests.rs b/precompiles/balances-erc20/src/tests.rs index 6e176e808..c245fe3e1 100644 --- a/precompiles/balances-erc20/src/tests.rs +++ b/precompiles/balances-erc20/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use std::str::from_utf8; diff --git a/precompiles/batch/Batch.sol b/precompiles/batch/Batch.sol index d4069d1b2..887442131 100644 --- a/precompiles/batch/Batch.sol +++ b/precompiles/batch/Batch.sol @@ -7,7 +7,8 @@ address constant BATCH_ADDRESS = 0x0000000000000000000000000000000000000808; /// @dev The Batch contract's instance. Batch constant BATCH_CONTRACT = Batch(BATCH_ADDRESS); -/// @author The Moonbeam Team +/// @author Tangle Network +/// @author Originally built by Moonbeam Team /// @title Batch precompile /// @dev Allows to perform multiple calls throught one call to the precompile. /// Can be used by EOA to do multiple calls in a single transaction. diff --git a/precompiles/call-permit/CallPermit.sol b/precompiles/call-permit/CallPermit.sol index 1cc484356..2dece6886 100644 --- a/precompiles/call-permit/CallPermit.sol +++ b/precompiles/call-permit/CallPermit.sol @@ -7,7 +7,8 @@ address constant CALL_PERMIT_ADDRESS = 0x000000000000000000000000000000000000080 /// @dev The CallPermit contract's instance. CallPermit constant CALL_PERMIT_CONTRACT = CallPermit(CALL_PERMIT_ADDRESS); -/// @author The Moonbeam Team +/// @author Tangle Network +/// @author Originally built by Moonbeam Team /// @title Call Permit Interface /// @dev The interface aims to be a general-purpose tool to perform gas-less transactions. It uses the EIP-712 standard, /// and signed messages can be dispatched by another network participant with a transaction diff --git a/precompiles/pallet-democracy/DemocracyInterface.sol b/precompiles/pallet-democracy/DemocracyInterface.sol index bb6b9dfe3..bb0b596b1 100644 --- a/precompiles/pallet-democracy/DemocracyInterface.sol +++ b/precompiles/pallet-democracy/DemocracyInterface.sol @@ -7,7 +7,8 @@ address constant DEMOCRACY_ADDRESS = 0x0000000000000000000000000000000000000803; /// @dev The Democracy contract's instance. Democracy constant DEMOCRACY_CONTRACT = Democracy(DEMOCRACY_ADDRESS); -/// @author The Moonbeam Team +/// @author Tangle Network +/// @author Originally built by Moonbeam Team /// @title Pallet Democracy Interface /// @dev The interface through which solidity contracts will interact with pallet-democracy. /// This interface does not exhaustively wrap pallet democracy, rather it wraps the most diff --git a/precompiles/precompile-registry/PrecompileRegistry.sol b/precompiles/precompile-registry/PrecompileRegistry.sol index 61b06db80..3c8fb218b 100644 --- a/precompiles/precompile-registry/PrecompileRegistry.sol +++ b/precompiles/precompile-registry/PrecompileRegistry.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.8.3; -/// @author The Moonbeam Team +/// @author Tangle Network +/// @author Originally built by Moonbeam Team /// @title Precompile Registry /// @dev Interface to the set of available precompiles. interface PrecompileRegistry { diff --git a/precompiles/preimage/Preimage.sol b/precompiles/preimage/Preimage.sol index f68a59985..6e93b1972 100644 --- a/precompiles/preimage/Preimage.sol +++ b/precompiles/preimage/Preimage.sol @@ -7,7 +7,8 @@ address constant PREIMAGE_ADDRESS = 0x0000000000000000000000000000000000000813; /// @dev The Preimage contract's instance. Preimage constant PREIMAGE_CONTRACT = Preimage(PREIMAGE_ADDRESS); -/// @author The Moonbeam Team +/// @author Tangle Network +/// @author Originally built by Moonbeam Team /// @title Pallet Preimage Interface /// @title The interface through which solidity contracts will interact with the Preimage pallet /// @custom:address 0x0000000000000000000000000000000000000813 diff --git a/precompiles/proxy/Proxy.sol b/precompiles/proxy/Proxy.sol index d568fce51..b9fc088c5 100644 --- a/precompiles/proxy/Proxy.sol +++ b/precompiles/proxy/Proxy.sol @@ -7,7 +7,8 @@ address constant PROXY_ADDRESS = 0x000000000000000000000000000000000000080b; /// @dev The Proxy contract's instance. Proxy constant PROXY_CONTRACT = Proxy(PROXY_ADDRESS); -/// @author The Moonbeam Team +/// @author Tangle Network +/// @author Originally built by Moonbeam Team /// @title Pallet Proxy Interface /// @title The interface through which solidity contracts will interact with the Proxy pallet /// @custom:address 0x000000000000000000000000000000000000080b diff --git a/primitives/ext/src/lib.rs b/primitives/ext/src/lib.rs index 57351aaf2..2152ed2f3 100644 --- a/primitives/ext/src/lib.rs +++ b/primitives/ext/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! Environmental-aware externalities for EVM tracing in Wasm runtime. This enables //! capturing the - potentially large - trace output data in the host and keep @@ -46,7 +47,7 @@ pub trait Ext { fn call_list_new(&mut self) {} // New design, proxy events. - /// An `Evm` event proxied by the Moonbeam runtime to this host function. + /// An `Evm` event proxied by the Tangle runtime to this host function. /// evm -> runtime -> host. fn evm_event(&mut self, event: Vec) { if let Ok(event) = EvmEvent::decode(&mut &event[..]) { @@ -54,7 +55,7 @@ pub trait Ext { } } - /// A `Gasometer` event proxied by the Moonbeam runtime to this host function. + /// A `Gasometer` event proxied by the Tangle runtime to this host function. /// evm_gasometer -> runtime -> host. fn gasometer_event(&mut self, event: Vec) { if let Ok(event) = GasometerEvent::decode(&mut &event[..]) { @@ -62,7 +63,7 @@ pub trait Ext { } } - /// A `Runtime` event proxied by the Moonbeam runtime to this host function. + /// A `Runtime` event proxied by the Tangle runtime to this host function. /// evm_runtime -> runtime -> host. fn runtime_event(&mut self, event: Vec) { if let Ok(event) = RuntimeEvent::decode(&mut &event[..]) { diff --git a/primitives/rpc/debug/src/lib.rs b/primitives/rpc/debug/src/lib.rs index f041fd975..e518d19b1 100644 --- a/primitives/rpc/debug/src/lib.rs +++ b/primitives/rpc/debug/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . #![cfg_attr(not(feature = "std"), no_std)] diff --git a/primitives/rpc/evm-tracing-events/src/evm.rs b/primitives/rpc/evm-tracing-events/src/evm.rs index 2b997eaeb..c305aabe9 100644 --- a/primitives/rpc/evm-tracing-events/src/evm.rs +++ b/primitives/rpc/evm-tracing-events/src/evm.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . extern crate alloc; diff --git a/primitives/rpc/evm-tracing-events/src/gasometer.rs b/primitives/rpc/evm-tracing-events/src/gasometer.rs index 85d8352ba..4491e9585 100644 --- a/primitives/rpc/evm-tracing-events/src/gasometer.rs +++ b/primitives/rpc/evm-tracing-events/src/gasometer.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . use parity_scale_codec::{Decode, Encode}; diff --git a/primitives/rpc/evm-tracing-events/src/lib.rs b/primitives/rpc/evm-tracing-events/src/lib.rs index 6a0e5923c..84db315f5 100644 --- a/primitives/rpc/evm-tracing-events/src/lib.rs +++ b/primitives/rpc/evm-tracing-events/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . //! A Proxy in this context is an environmental trait implementor meant to be used for capturing //! EVM trace events sent to a Host function from the Runtime. Works like: diff --git a/primitives/rpc/evm-tracing-events/src/runtime.rs b/primitives/rpc/evm-tracing-events/src/runtime.rs index 089932d55..6b4552f47 100644 --- a/primitives/rpc/evm-tracing-events/src/runtime.rs +++ b/primitives/rpc/evm-tracing-events/src/runtime.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . extern crate alloc; diff --git a/primitives/rpc/txpool/src/lib.rs b/primitives/rpc/txpool/src/lib.rs index c3c75aae5..befe02521 100644 --- a/primitives/rpc/txpool/src/lib.rs +++ b/primitives/rpc/txpool/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. +// Copyright 2022-2025 Tangle Foundation. +// This file is part of Tangle. +// This file originated in Moonbeam's codebase. -// Moonbeam is free software: you can redistribute it and/or modify +// Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Moonbeam is distributed in the hope that it will be useful, +// Tangle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . +// along with Tangle. If not, see . #![cfg_attr(not(feature = "std"), no_std)] // These clippy lints are disabled because the macro-generated code triggers them. From ebb1c7934694e0fe76f8939f834252d6a7cd85f6 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 14:51:40 +0900 Subject: [PATCH 05/20] chore: HAL-014 --- client/rpc-core/txpool/src/types/content.rs | 2 +- client/rpc/trace/src/lib.rs | 4 ++-- pallets/multi-asset-delegation/src/mock.rs | 6 +++--- pallets/rewards/src/mock.rs | 2 +- pallets/services/src/mock.rs | 2 +- precompiles/assets-erc20/src/lib.rs | 2 +- precompiles/assets-erc20/src/mock.rs | 4 ++-- precompiles/batch/src/lib.rs | 2 +- precompiles/multi-asset-delegation/src/mock.rs | 6 +++--- precompiles/precompile-registry/src/lib.rs | 2 +- precompiles/rewards/src/mock.rs | 6 +++--- precompiles/services/src/mock.rs | 2 +- 12 files changed, 20 insertions(+), 20 deletions(-) diff --git a/client/rpc-core/txpool/src/types/content.rs b/client/rpc-core/txpool/src/types/content.rs index 31458ca48..920ad83d5 100644 --- a/client/rpc-core/txpool/src/types/content.rs +++ b/client/rpc-core/txpool/src/types/content.rs @@ -38,7 +38,7 @@ pub struct Transaction { /// Recipient #[serde(serialize_with = "to_serialize")] pub to: Option, - /// Transfered value + /// Transferred value pub value: U256, /// Gas Price pub gas_price: U256, diff --git a/client/rpc/trace/src/lib.rs b/client/rpc/trace/src/lib.rs index 80f9cc754..7c5cb141f 100644 --- a/client/rpc/trace/src/lib.rs +++ b/client/rpc/trace/src/lib.rs @@ -328,7 +328,7 @@ impl CacheRequester { /// Data stored for each block in the cache. /// `active_batch_count` represents the number of batches using this -/// block. It will increase immediatly when a batch is created, but will be +/// block. It will increase immediately when a batch is created, but will be /// decrease only after the batch ends and its expiration delay passes. /// It allows to keep the data in the cache for following requests that would use /// this block, which is important to handle pagination efficiently. @@ -595,7 +595,7 @@ where } /// Handle a request to get the traces of the provided block. - /// - If the result is stored in the cache, it sends it immediatly. + /// - If the result is stored in the cache, it sends it immediately. /// - If the block is currently being pooled, it is added in this block cache waiting list, and /// all requests concerning this block will be satisfied when the tracing for this block is /// finished. diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index 368331658..c645f4468 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -278,12 +278,12 @@ pub struct MockServiceManager; impl tangle_primitives::traits::ServiceManager for MockServiceManager { fn get_active_blueprints_count(_account: &AccountId) -> usize { - // we dont care + // we don't care Default::default() } fn get_active_services_count(_account: &AccountId) -> usize { - // we dont care + // we don't care Default::default() } @@ -293,7 +293,7 @@ impl tangle_primitives::traits::ServiceManager for MockServi } fn get_blueprints_by_operator(_account: &AccountId) -> Vec { - todo!(); // we dont care + todo!(); // we don't care } } diff --git a/pallets/rewards/src/mock.rs b/pallets/rewards/src/mock.rs index 206e77e15..813c84eea 100644 --- a/pallets/rewards/src/mock.rs +++ b/pallets/rewards/src/mock.rs @@ -268,7 +268,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo bool { - // dont care + // don't care true } diff --git a/pallets/services/src/mock.rs b/pallets/services/src/mock.rs index 6d9afff49..7ba34ad80 100644 --- a/pallets/services/src/mock.rs +++ b/pallets/services/src/mock.rs @@ -271,7 +271,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo bool { - // dont care + // don't care true } diff --git a/precompiles/assets-erc20/src/lib.rs b/precompiles/assets-erc20/src/lib.rs index 3c032ed27..35977035b 100644 --- a/precompiles/assets-erc20/src/lib.rs +++ b/precompiles/assets-erc20/src/lib.rs @@ -121,7 +121,7 @@ where <::RuntimeCall as Dispatchable>::RuntimeOrigin: OriginTrait, AssetIdOf: Display, { - /// PrecompileSet discriminant. Allows to knows if the address maps to an asset id, + /// PrecompileSet discriminant. Allows knowing if the address maps to an asset id, /// and if this is the case which one. #[precompile::discriminant] fn discriminant(address: H160, gas: u64) -> DiscriminantResult> { diff --git a/precompiles/assets-erc20/src/mock.rs b/precompiles/assets-erc20/src/mock.rs index b013d8ecd..0f4fc9aa3 100644 --- a/precompiles/assets-erc20/src/mock.rs +++ b/precompiles/assets-erc20/src/mock.rs @@ -202,8 +202,8 @@ pallet_assets::runtime_benchmarks_enabled! { } } -// These parameters dont matter much as this will only be called by root with the forced arguments -// No deposit is substracted with those methods +// These parameters don't matter much as this will only be called by root with the forced arguments +// No deposit is subtracted with those methods parameter_types! { pub const AssetDeposit: Balance = 0; pub const ApprovalDeposit: Balance = 0; diff --git a/precompiles/batch/src/lib.rs b/precompiles/batch/src/lib.rs index d26ac2ba1..4102b6834 100644 --- a/precompiles/batch/src/lib.rs +++ b/precompiles/batch/src/lib.rs @@ -223,7 +223,7 @@ where return Err(PrecompileFailure::Fatal { exit_status }) }, - // BatchAll : Reverts and errors are immediatly forwarded. + // BatchAll : Reverts and errors are immediately forwarded. (Mode::BatchAll, ExitReason::Revert(exit_status)) => { return Err(PrecompileFailure::Revert { exit_status, output }) }, diff --git a/precompiles/multi-asset-delegation/src/mock.rs b/precompiles/multi-asset-delegation/src/mock.rs index 55ed9f4de..2f68c7c19 100644 --- a/precompiles/multi-asset-delegation/src/mock.rs +++ b/precompiles/multi-asset-delegation/src/mock.rs @@ -253,12 +253,12 @@ pub struct MockServiceManager; impl ServiceManager for MockServiceManager { fn get_active_blueprints_count(_account: &AccountId) -> usize { - // we dont care + // we don't care Default::default() } fn get_active_services_count(_account: &AccountId) -> usize { - // we dont care + // we don't care Default::default() } @@ -268,7 +268,7 @@ impl ServiceManager for MockServiceManager { } fn get_blueprints_by_operator(_account: &AccountId) -> Vec { - // we dont care + // we don't care Default::default() } } diff --git a/precompiles/precompile-registry/src/lib.rs b/precompiles/precompile-registry/src/lib.rs index 15e94ee07..ab994e0fc 100644 --- a/precompiles/precompile-registry/src/lib.rs +++ b/precompiles/precompile-registry/src/lib.rs @@ -92,7 +92,7 @@ where // pallet_evm::create_account read storage item pallet_evm::AccountCodes // // AccountCodes: Blake2128(16) + H160(20) + Vec(5) - // We asume an existing precompile can hold at most 5 bytes worth of dummy code. + // We assume an existing precompile can hold at most 5 bytes worth of dummy code. handle.record_db_read::(41)?; pallet_evm::Pallet::::create_account(address.0, DUMMY_CODE.to_vec()); diff --git a/precompiles/rewards/src/mock.rs b/precompiles/rewards/src/mock.rs index 6d5407aac..f505db12c 100644 --- a/precompiles/rewards/src/mock.rs +++ b/precompiles/rewards/src/mock.rs @@ -239,12 +239,12 @@ pub struct MockServiceManager; impl ServiceManager for MockServiceManager { fn get_active_blueprints_count(_account: &AccountId) -> usize { - // we dont care + // we don't care Default::default() } fn get_active_services_count(_account: &AccountId) -> usize { - // we dont care + // we don't care Default::default() } @@ -254,7 +254,7 @@ impl ServiceManager for MockServiceManager { } fn get_blueprints_by_operator(_account: &AccountId) -> Vec { - // we dont care + // we don't care Default::default() } } diff --git a/precompiles/services/src/mock.rs b/precompiles/services/src/mock.rs index ef41b0842..9fcdb89a9 100644 --- a/precompiles/services/src/mock.rs +++ b/precompiles/services/src/mock.rs @@ -402,7 +402,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo bool { - // dont care + // don't care true } From 1468104b04d5ee98e7c4919f8214be741038c513 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 15:02:04 +0900 Subject: [PATCH 06/20] chore: checked math fix + HAL-013 --- .../src/functions/delegate.rs | 4 ++-- pallets/multi-asset-delegation/src/lib.rs | 2 ++ .../src/types/delegator.rs | 17 +++++++++-------- .../src/types/operator.rs | 3 ++- precompiles/staking/src/lib.rs | 16 ++++++++-------- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 1ec047a02..7f29acd40 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -21,7 +21,7 @@ use frame_support::{ traits::{fungibles::Mutate, tokens::Preservation, Get}, }; use sp_runtime::{ - traits::{CheckedSub, Zero}, + traits::{CheckedAdd, CheckedSub, Zero}, DispatchError, Percent, }; use sp_std::vec::Vec; @@ -217,7 +217,7 @@ impl Pallet { operator_metadata.delegations.remove(operator_delegation_index); operator_metadata.delegation_count = operator_metadata .delegation_count - .checked_sub(&1) + .checked_sub(1u32) .ok_or(Error::::InsufficientBalance)?; } diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 864b64165..48f5d095d 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -411,6 +411,8 @@ pub mod pallet { LockViolation, /// Above deposit caps setup DepositExceedsCapForAsset, + /// Overflow from math + OverflowRisk, } /// Hooks for the pallet. diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 19c1d324f..f65fda38b 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -15,13 +15,14 @@ // along with Tangle. If not, see . use super::*; -use frame_support::ensure; -use frame_support::{pallet_prelude::Get, BoundedVec}; -use sp_std::fmt::Debug; -use sp_std::vec; -use tangle_primitives::types::rewards::LockInfo; -use tangle_primitives::types::rewards::LockMultiplier; -use tangle_primitives::{services::Asset, BlueprintId}; +use frame_support::{ensure, pallet_prelude::Get, BoundedVec}; +use sp_runtime::traits::CheckedAdd; +use sp_std::{fmt::Debug, vec}; +use tangle_primitives::{ + services::Asset, + types::rewards::{LockInfo, LockMultiplier}, + BlueprintId, +}; /// Represents how a delegator selects which blueprints to work with. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] @@ -186,7 +187,7 @@ impl< pub fn calculate_delegation_by_asset(&self, asset_id: Asset) -> Balance // Asset) -> Balance where - Balance: Default + core::ops::AddAssign + Clone, + Balance: Default + core::ops::AddAssign + Clone + CheckedAdd, AssetId: Eq + PartialEq, { let mut total = Balance::default(); diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index a92171ae9..5c1977a62 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -16,6 +16,7 @@ use super::*; use frame_support::{pallet_prelude::*, BoundedVec}; +use sp_runtime::traits::CheckedAdd; use tangle_primitives::services::Asset; /// A snapshot of the operator state at the start of the round. @@ -34,7 +35,7 @@ impl> OperatorSnapshot where AssetId: PartialEq + Ord + Copy, - Balance: Default + core::ops::AddAssign + Copy, + Balance: Default + core::ops::AddAssign + Copy + CheckedAdd, { /// Calculates the total stake for a specific asset ID from all delegations. pub fn get_stake_by_asset_id(&self, asset_id: Asset) -> Balance { diff --git a/precompiles/staking/src/lib.rs b/precompiles/staking/src/lib.rs index a4f09258d..1249f83c4 100644 --- a/precompiles/staking/src/lib.rs +++ b/precompiles/staking/src/lib.rs @@ -137,9 +137,9 @@ where #[precompile::public("minNominatorBond()")] #[precompile::public("min_nominator_bond()")] #[precompile::view] - fn min_nominator_bond(handle: &mut impl PrecompileHandle) -> EvmResult { + fn min_nominator_bond(handle: &mut impl PrecompileHandle) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let min_nominator_bond: u128 = pallet_staking::MinNominatorBond::::get() + let min_nominator_bond: U256 = pallet_staking::MinNominatorBond::::get() .try_into() .map_err(|_| revert("Amount is too large for provided balance type"))?; Ok(min_nominator_bond) @@ -148,9 +148,9 @@ where #[precompile::public("minValidatorBond()")] #[precompile::public("min_validator_bond()")] #[precompile::view] - fn min_validator_bond(handle: &mut impl PrecompileHandle) -> EvmResult { + fn min_validator_bond(handle: &mut impl PrecompileHandle) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let min_validator_bond: u128 = pallet_staking::MinValidatorBond::::get() + let min_validator_bond: U256 = pallet_staking::MinValidatorBond::::get() .try_into() .map_err(|_| revert("Amount is too large for provided balance type"))?; Ok(min_validator_bond) @@ -159,9 +159,9 @@ where #[precompile::public("minActiveStake()")] #[precompile::public("min_active_stake()")] #[precompile::view] - fn min_active_stake(handle: &mut impl PrecompileHandle) -> EvmResult { + fn min_active_stake(handle: &mut impl PrecompileHandle) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let min_active_stake: u128 = pallet_staking::MinimumActiveStake::::get() + let min_active_stake: U256 = pallet_staking::MinimumActiveStake::::get() .try_into() .map_err(|_| revert("Amount is too large for provided balance type"))?; Ok(min_active_stake) @@ -209,9 +209,9 @@ where #[precompile::public("erasTotalStake(uint32)")] #[precompile::public("eras_total_stake(uint32)")] #[precompile::view] - fn eras_total_stake(handle: &mut impl PrecompileHandle, era_index: u32) -> EvmResult { + fn eras_total_stake(handle: &mut impl PrecompileHandle, era_index: u32) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let total_stake: u128 = >::eras_total_stake(era_index) + let total_stake: U256 = >::eras_total_stake(era_index) .try_into() .map_err(|_| revert("Amount is too large for provided balance type"))?; From 48375480ae838a5845edbda969902a064e398f28 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 15:03:00 +0900 Subject: [PATCH 07/20] chore: Remove unused error HAL-004 --- pallets/multi-asset-delegation/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 48f5d095d..c2aef9d1d 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -319,8 +319,6 @@ pub mod pallet { AlreadyLeaving, /// The account is not leaving as an operator. NotLeavingOperator, - /// The round does not match the scheduled leave round. - NotLeavingRound, /// Leaving round not reached LeavingRoundNotReached, /// There is no scheduled unstake request. From b691bfd36e2a02e782bc5a4d1aaf739a98feca33 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 15:08:11 +0900 Subject: [PATCH 08/20] chore: HAL-023 --- precompiles/staking/StakingInterface.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/precompiles/staking/StakingInterface.sol b/precompiles/staking/StakingInterface.sol index e0ff826c7..b18541cdb 100644 --- a/precompiles/staking/StakingInterface.sol +++ b/precompiles/staking/StakingInterface.sol @@ -51,6 +51,11 @@ interface Staking { /// @return Total stake in era. function erasTotalStake(uint32 eraIndex) external view returns (uint256); + /// @dev Get total reward points for an era + /// @param eraIndex The era index to query + /// @return Total reward points for the era + function erasTotalRewardPoints(uint32 eraIndex) external view returns (uint32); + /// @dev Nominate a set of validators. /// @param targets Array of validators' addresses to nominate. function nominate(bytes32[] calldata targets) external; From cee27d7addfafa9797dcdf2b7b6788c832cae7e4 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 15:10:28 +0900 Subject: [PATCH 09/20] chore: HAL-010 --- primitives/rpc/evm-tracing-events/src/gasometer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/rpc/evm-tracing-events/src/gasometer.rs b/primitives/rpc/evm-tracing-events/src/gasometer.rs index 4491e9585..2edfd82d4 100644 --- a/primitives/rpc/evm-tracing-events/src/gasometer.rs +++ b/primitives/rpc/evm-tracing-events/src/gasometer.rs @@ -27,7 +27,7 @@ pub struct Snapshot { impl Snapshot { pub fn gas(&self) -> u64 { - self.gas_limit - self.used_gas - self.memory_gas + (self.gas_limit.saturating_sub(self.used_gas)).saturating_sub(self.memory_gas) } } From d521deb3b0ab21ab8da23c8d3d17911a9210e23b Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 15:10:50 +0900 Subject: [PATCH 10/20] chore: HAL-022 --- precompiles/staking/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/precompiles/staking/src/lib.rs b/precompiles/staking/src/lib.rs index 1249f83c4..9c073ba46 100644 --- a/precompiles/staking/src/lib.rs +++ b/precompiles/staking/src/lib.rs @@ -202,7 +202,7 @@ where fn is_nominator(handle: &mut impl PrecompileHandle, nominator: Address) -> EvmResult { let nominator_account = Runtime::AddressMapping::into_account_id(nominator.0); handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let is_nominator = pallet_staking::Validators::::contains_key(nominator_account); + let is_nominator = pallet_staking::Nominators::::contains_key(nominator_account); Ok(is_nominator) } From d596301b04e27adcb2847d98808becc889534ed4 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 21 Jan 2025 15:30:55 +0900 Subject: [PATCH 11/20] chore: HAL-020 MADS precompile, removing all operator functions, make it inaccessible to be an operator from precompile --- .../MultiAssetDelegation.sol | 43 ------ .../multi-asset-delegation/fuzzer/call.rs | 137 ------------------ precompiles/multi-asset-delegation/src/lib.rs | 122 ---------------- .../multi-asset-delegation/src/tests.rs | 72 --------- 4 files changed, 374 deletions(-) diff --git a/precompiles/multi-asset-delegation/MultiAssetDelegation.sol b/precompiles/multi-asset-delegation/MultiAssetDelegation.sol index 48e461d74..6b83ee281 100644 --- a/precompiles/multi-asset-delegation/MultiAssetDelegation.sol +++ b/precompiles/multi-asset-delegation/MultiAssetDelegation.sol @@ -12,49 +12,6 @@ MultiAssetDelegation constant MULTI_ASSET_DELEGATION_CONTRACT = MultiAssetDelega /// @title The interface through which solidity contracts will interact with the MultiAssetDelegation pallet /// @custom:address 0x0000000000000000000000000000000000000822 interface MultiAssetDelegation { - /// @dev Join as an operator with a bond amount. - /// @param bondAmount The amount to bond as an operator. - /// @custom:selector de883d74 - function joinOperators(uint256 bondAmount) external; - - /// @dev Schedule to leave as an operator. - /// @custom:selector ce3edd76 - function scheduleLeaveOperators() external; - - /// @dev Cancel the scheduled leave as an operator. - /// @custom:selector 9b1300c1 - function cancelLeaveOperators() external; - - /// @dev Execute the leave as an operator. - /// @custom:selector 0de1fc17 - function executeLeaveOperators() external; - - /// @dev Bond more as an operator. - /// @param additionalBond The additional amount to bond. - /// @custom:selector eede281b - function operatorBondMore(uint256 additionalBond) external; - - /// @dev Schedule to unstake as an operator. - /// @param unstakeAmount The amount to unstake. - /// @custom:selector 44aff252 - function scheduleOperatorUnstake(uint256 unstakeAmount) external; - - /// @dev Execute the unstake as an operator. - /// @custom:selector b0dfce06 - function executeOperatorUnstake() external; - - /// @dev Cancel the scheduled unstake as an operator. - /// @custom:selector ac359f2b - function cancelOperatorUnstake() external; - - /// @dev Go offline as an operator. - /// @custom:selector a6485ccd - function goOffline() external; - - /// @dev Go online as an operator. - /// @custom:selector 6e5b676b - function goOnline() external; - /// @dev Deposit an amount of an asset. /// @param assetId The ID of the asset (0 for ERC20). /// @param tokenAddress The address of the ERC20 token (if assetId is 0). diff --git a/precompiles/multi-asset-delegation/fuzzer/call.rs b/precompiles/multi-asset-delegation/fuzzer/call.rs index 963d16147..f98d75b4e 100644 --- a/precompiles/multi-asset-delegation/fuzzer/call.rs +++ b/precompiles/multi-asset-delegation/fuzzer/call.rs @@ -94,74 +94,6 @@ fn join_operators_call(rng: &mut R, who: &Address) -> (PCall, Address) { fn random_calls(mut rng: &mut R) -> impl IntoIterator { let op = PCall::selectors().choose(rng).cloned().unwrap(); match op { - _ if op == PCall::join_operators_selectors()[0] => { - // join_operators - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(&mut rng, &who)] - }, - _ if op == PCall::schedule_leave_operators_selectors()[0] => { - // Schedule leave operators - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::schedule_leave_operators {}, who)] - }, - _ if op == PCall::cancel_leave_operators_selectors()[0] => { - // Cancel leave operators - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::cancel_leave_operators {}, who)] - }, - _ if op == PCall::execute_leave_operators_selectors()[0] => { - // Execute leave operators - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::execute_leave_operators {}, who)] - }, - _ if op == PCall::operator_bond_more_selectors()[0] => { - // Operator bond more - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - let additional_bond = random_ed_multiple(&mut rng).into(); - vec![ - join_operators_call(rng, &who), - (PCall::operator_bond_more { additional_bond }, who), - ] - }, - _ if op == PCall::schedule_operator_unstake_selectors()[0] => { - // Schedule operator unstake - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - let unstake_amount = random_ed_multiple(&mut rng).into(); - vec![ - join_operators_call(rng, &who), - (PCall::schedule_operator_unstake { unstake_amount }, who), - ] - }, - _ if op == PCall::execute_operator_unstake_selectors()[0] => { - // Execute operator unstake - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::execute_operator_unstake {}, who)] - }, - _ if op == PCall::cancel_operator_unstake_selectors()[0] => { - // Cancel operator unstake - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::cancel_operator_unstake {}, who)] - }, - _ if op == PCall::go_offline_selectors()[0] => { - // Go offline - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::go_offline {}, who)] - }, - _ if op == PCall::go_online_selectors()[0] => { - // Go online - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::go_online {}, who)] - }, _ if op == PCall::deposit_selectors()[0] => { // Deposit let who = random_address(&mut rng); @@ -342,75 +274,6 @@ fn main() { fn do_sanity_checks(call: PCall, origin: Address, outcome: PrecompileOutput) { let caller = >::into_account_id(origin.0); match call { - PCall::join_operators { bond_amount } => { - assert!(mad::Operators::::contains_key(caller), "operator not found"); - assert_eq!( - MultiAssetDelegation::operator_info(caller).unwrap_or_default().stake, - bond_amount.as_u64() - ); - assert!( - Balances::reserved_balance(caller).ge(&bond_amount.as_u64()), - "bond amount not reserved" - ); - }, - PCall::schedule_leave_operators {} => { - assert!(mad::Operators::::contains_key(caller), "operator not found"); - let current_round = mad::CurrentRound::::get(); - let leaving_time = - <::LeaveOperatorsDelay as Get>::get() + current_round; - assert_eq!( - mad::Operators::::get(caller).unwrap_or_default().status, - OperatorStatus::Leaving(leaving_time) - ); - }, - PCall::cancel_leave_operators {} => { - assert_eq!( - mad::Operators::::get(caller).unwrap_or_default().status, - OperatorStatus::Active - ); - }, - PCall::execute_leave_operators {} => { - assert!(!mad::Operators::::contains_key(caller), "operator not removed"); - assert!(Balances::reserved_balance(caller).is_zero(), "bond amount not unreserved"); - }, - PCall::operator_bond_more { additional_bond } => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - assert!(info.stake.ge(&additional_bond.as_u64()), "bond amount not increased"); - assert!( - Balances::reserved_balance(caller).ge(&additional_bond.as_u64()), - "bond amount not reserved" - ); - }, - PCall::schedule_operator_unstake { unstake_amount } => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - let current_round = MultiAssetDelegation::current_round(); - let unstake_request = OperatorBondLessRequest { - amount: unstake_amount.as_u64(), - request_time: current_round, - }; - assert_eq!(info.request, Some(unstake_request), "unstake request not set"); - }, - PCall::execute_operator_unstake {} => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - assert!(info.request.is_none(), "unstake request not removed"); - // reserved balance should be reduced and equal to the stake - assert!( - Balances::reserved_balance(caller).eq(&info.stake), - "reserved balance not equal to stake" - ); - }, - PCall::cancel_operator_unstake {} => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - assert!(info.request.is_none(), "unstake request not removed"); - }, - PCall::go_offline {} => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - assert_eq!(info.status, OperatorStatus::Inactive, "status not set to inactive"); - }, - PCall::go_online {} => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - assert_eq!(info.status, OperatorStatus::Active, "status not set to active"); - }, PCall::deposit { asset_id, amount, token_address, lock_multiplier: 0 } => { let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) if erc20_token != [0; 20] => { diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index e29cfad2c..1d898556a 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -120,66 +120,6 @@ where Ok(amount.into()) } - #[precompile::public("joinOperators(uint256)")] - fn join_operators(handle: &mut impl PrecompileHandle, bond_amount: U256) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let bond_amount: BalanceOf = - bond_amount.try_into().map_err(|_| revert("Invalid bond amount"))?; - let call = pallet_multi_asset_delegation::Call::::join_operators { bond_amount }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("scheduleLeaveOperators()")] - fn schedule_leave_operators(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::schedule_leave_operators {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("cancelLeaveOperators()")] - fn cancel_leave_operators(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::cancel_leave_operators {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("executeLeaveOperators()")] - fn execute_leave_operators(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::execute_leave_operators {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("operatorBondMore(uint256)")] - fn operator_bond_more(handle: &mut impl PrecompileHandle, additional_bond: U256) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let additional_bond: BalanceOf = - additional_bond.try_into().map_err(|_| revert("Invalid bond amount"))?; - let call = - pallet_multi_asset_delegation::Call::::operator_bond_more { additional_bond }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - #[precompile::public("executeWithdraw()")] fn execute_withdraw(handle: &mut impl PrecompileHandle) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; @@ -214,68 +154,6 @@ where Ok(()) } - #[precompile::public("scheduleOperatorUnstake(uint256)")] - fn schedule_operator_unstake( - handle: &mut impl PrecompileHandle, - unstake_amount: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let unstake_amount: BalanceOf = - unstake_amount.try_into().map_err(|_| revert("Invalid unstake amount"))?; - let call = pallet_multi_asset_delegation::Call::::schedule_operator_unstake { - unstake_amount, - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("executeOperatorUnstake()")] - fn execute_operator_unstake(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::execute_operator_unstake {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("cancelOperatorUnstake()")] - fn cancel_operator_unstake(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::cancel_operator_unstake {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("goOffline()")] - fn go_offline(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::go_offline {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("goOnline()")] - fn go_online(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::go_online {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - #[precompile::public("deposit(uint256,address,uint256,uint8)")] fn deposit( handle: &mut impl PrecompileHandle, diff --git a/precompiles/multi-asset-delegation/src/tests.rs b/precompiles/multi-asset-delegation/src/tests.rs index 1a7ef646b..969c902fa 100644 --- a/precompiles/multi-asset-delegation/src/tests.rs +++ b/precompiles/multi-asset-delegation/src/tests.rs @@ -34,45 +34,6 @@ fn test_unimplemented_selector_reverts() { }); } -#[test] -fn test_join_operators() { - ExtBuilder::default().build().execute_with(|| { - let account = sp_core::sr25519::Public::from(TestAccount::Alex); - let initial_balance = Balances::free_balance(account); - assert!(Operators::::get(account).is_none()); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::join_operators { bond_amount: U256::from(10_000) }, - ) - .execute_returns(()); - - assert!(Operators::::get(account).is_some()); - let expected_balance = initial_balance - 10_000; - assert_eq!(Balances::free_balance(account), expected_balance); - }); -} - -#[test] -fn test_join_operators_insufficient_balance() { - ExtBuilder::default().build().execute_with(|| { - let account = sp_core::sr25519::Public::from(TestAccount::Eve); - Balances::make_free_balance_be(&account, 500); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Eve, - H160::from_low_u64_be(1), - PCall::join_operators { bond_amount: U256::from(10_000) }, - ) - .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 1, error: [2, 0, 0, 0], message: Some(\"InsufficientBalance\") })"); - - assert_eq!(Balances::free_balance(account), 500); - }); -} - #[test] fn test_delegate_assets_invalid_operator() { ExtBuilder::default().build().execute_with(|| { @@ -666,39 +627,6 @@ fn test_cancel_withdraw() { }); } -#[test] -fn test_operator_go_offline_and_online() { - ExtBuilder::default().build().execute_with(|| { - let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); - - Balances::make_free_balance_be(&operator_account, 20_000); - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator_account), - 10_000 - )); - - PrecompilesValue::get() - .prepare_test(TestAccount::Bobo, H160::from_low_u64_be(1), PCall::go_offline {}) - .execute_returns(()); - - assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status - == OperatorStatus::Inactive - ); - - PrecompilesValue::get() - .prepare_test(TestAccount::Bobo, H160::from_low_u64_be(1), PCall::go_online {}) - .execute_returns(()); - - assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status - == OperatorStatus::Active - ); - - assert_eq!(Balances::free_balance(operator_account), 20_000 - 10_000); - }); -} - #[test] fn balance_of_works() { ExtBuilder::default().build().execute_with(|| { From b8604983896e447fbfc58498675def51c84827c1 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 21 Jan 2025 10:41:05 +0400 Subject: [PATCH 12/20] add missing tangle lst precompiles --- Cargo.lock | 1 + precompiles/tangle-lst/Cargo.toml | 1 + precompiles/tangle-lst/TangleLst.sol | 40 +++++ precompiles/tangle-lst/src/lib.rs | 214 ++++++++++++++++++++++++++- 4 files changed, 248 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f9d5b9bd..15a1f0547 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9207,6 +9207,7 @@ dependencies = [ "scale-info", "serde", "sha3", + "sp-arithmetic", "sp-core", "sp-io", "sp-runtime", diff --git a/precompiles/tangle-lst/Cargo.toml b/precompiles/tangle-lst/Cargo.toml index 33c69e91b..83b7d7b6d 100644 --- a/precompiles/tangle-lst/Cargo.toml +++ b/precompiles/tangle-lst/Cargo.toml @@ -19,6 +19,7 @@ parity-scale-codec = { workspace = true, features = ["derive"] } sp-core = { workspace = true } sp-runtime = { workspace = true } sp-std = { workspace = true } +sp-arithmetic = { workspace = true } # Frontier fp-evm = { workspace = true } diff --git a/precompiles/tangle-lst/TangleLst.sol b/precompiles/tangle-lst/TangleLst.sol index a9568b14f..68ca5c5dc 100644 --- a/precompiles/tangle-lst/TangleLst.sol +++ b/precompiles/tangle-lst/TangleLst.sol @@ -107,4 +107,44 @@ interface TangleLst { bytes32 nominator, bytes32 bouncer ) external returns (uint8); + + /// @dev Stop nominating for a pool + /// @param poolId The ID of the pool to chill + function chill(uint256 poolId) external; + + /// @dev Bond extra tokens for another account + /// @param poolId The ID of the pool + /// @param who The account to bond extra for + /// @param amount The amount to bond extra + function bondExtraOther(uint256 poolId, bytes32 who, uint256 amount) external; + + /// @dev Set commission for a pool + /// @param poolId The ID of the pool + /// @param newCommission The new commission value + /// @param payee The account to receive commission payments + function setCommission(uint256 poolId, uint256 newCommission, bytes32 payee) external; + + /// @dev Set maximum commission for a pool + /// @param poolId The ID of the pool + /// @param maxCommission The maximum commission value + function setCommissionMax(uint256 poolId, uint256 maxCommission) external; + + /// @dev Set commission change rate + /// @param poolId The ID of the pool + /// @param maxIncrease The maximum increase in commission + /// @param minDelay The minimum delay between changes + function setCommissionChangeRate(uint256 poolId, uint256 maxIncrease, uint256 minDelay) external; + + /// @dev Claim commission for a pool + /// @param poolId The ID of the pool + function claimCommission(uint256 poolId) external; + + /// @dev Adjust pool deposit + /// @param poolId The ID of the pool + function adjustPoolDeposit(uint256 poolId) external; + + /// @dev Set commission claim permission + /// @param poolId The ID of the pool + /// @param permission The permission value (as uint8) + function setCommissionClaimPermission(uint256 poolId, uint8 permission) external; } diff --git a/precompiles/tangle-lst/src/lib.rs b/precompiles/tangle-lst/src/lib.rs index 3d66f29f1..53e734fbf 100644 --- a/precompiles/tangle-lst/src/lib.rs +++ b/precompiles/tangle-lst/src/lib.rs @@ -42,9 +42,11 @@ use frame_support::{ dispatch::{GetDispatchInfo, PostDispatchInfo}, traits::Currency, }; +use frame_system::pallet_prelude::BlockNumberFor; use pallet_evm::AddressMapping; -use pallet_tangle_lst::{BondExtra, ConfigOp, PoolId, PoolState}; +use pallet_tangle_lst::{PoolId, PoolState}; use precompile_utils::prelude::*; +use sp_arithmetic::per_things::Perbill; use sp_core::{H160, H256, U256}; use sp_runtime::traits::{Dispatchable, StaticLookup}; use sp_std::{marker::PhantomData, vec::Vec}; @@ -96,7 +98,7 @@ where extra.try_into().map_err(|_| revert("Invalid extra amount"))?; let extra = match extra_type { - 0 => BondExtra::FreeBalance(extra), + 0 => pallet_tangle_lst::BondExtra::FreeBalance(extra), _ => return Err(revert("Invalid extra type")), }; @@ -295,21 +297,21 @@ where let pool_id: PoolId = pool_id.try_into().map_err(|_| revert("Invalid pool id"))?; let new_root = if new_root == H256::zero() { - ConfigOp::Noop + pallet_tangle_lst::ConfigOp::Noop } else { - ConfigOp::Set(Self::convert_to_account_id(new_root)?) + pallet_tangle_lst::ConfigOp::Set(Self::convert_to_account_id(new_root)?) }; let new_nominator = if new_nominator == H256::zero() { - ConfigOp::Noop + pallet_tangle_lst::ConfigOp::Noop } else { - ConfigOp::Set(Self::convert_to_account_id(new_nominator)?) + pallet_tangle_lst::ConfigOp::Set(Self::convert_to_account_id(new_nominator)?) }; let new_bouncer = if new_bouncer == H256::zero() { - ConfigOp::Noop + pallet_tangle_lst::ConfigOp::Noop } else { - ConfigOp::Set(Self::convert_to_account_id(new_bouncer)?) + pallet_tangle_lst::ConfigOp::Set(Self::convert_to_account_id(new_bouncer)?) }; let call = pallet_tangle_lst::Call::::update_roles { @@ -321,6 +323,202 @@ where RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; Ok(()) } + + #[precompile::public("chill(uint256)")] + fn chill(handle: &mut impl PrecompileHandle, pool_id: U256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + RuntimeHelper::::try_dispatch( + handle, + Some(origin).into(), + pallet_tangle_lst::Call::::chill { pool_id }, + )?; + + Ok(()) + } + + #[precompile::public("bondExtraOther(uint256,bytes32,uint256)")] + fn bond_extra_other( + handle: &mut impl PrecompileHandle, + pool_id: U256, + who: H256, + amount: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let member = Self::convert_to_account_id(who)?; + let extra = pallet_tangle_lst::BondExtra::FreeBalance( + amount.try_into().map_err(|_| revert("Amount overflow"))? + ); + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + RuntimeHelper::::try_dispatch( + handle, + Some(origin).into(), + pallet_tangle_lst::Call::::bond_extra_other { + pool_id, + member: Runtime::Lookup::unlookup(member), + extra, + }, + )?; + + Ok(()) + } + + #[precompile::public("setCommission(uint256,uint256)")] + fn set_commission( + handle: &mut impl PrecompileHandle, + pool_id: U256, + new_commission: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let commission_value: u32 = new_commission.try_into().map_err(|_| revert("Commission overflow"))?; + let commission = if commission_value == 0 { + None + } else { + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + Some((Perbill::from_parts(commission_value), origin)) + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_tangle_lst::Call::::set_commission { + pool_id, + new_commission: commission, + }, + )?; + + Ok(()) + } + + #[precompile::public("setCommissionMax(uint256,uint256)")] + fn set_commission_max( + handle: &mut impl PrecompileHandle, + pool_id: U256, + max_commission: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let max_commission_value: u32 = max_commission.try_into().map_err(|_| revert("Max commission overflow"))?; + let max_commission = Perbill::from_parts(max_commission_value); + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_tangle_lst::Call::::set_commission_max { + pool_id, + max_commission, + }, + )?; + + Ok(()) + } + + #[precompile::public("setCommissionChangeRate(uint256,uint256,uint256)")] + fn set_commission_change_rate( + handle: &mut impl PrecompileHandle, + pool_id: U256, + max_increase: U256, + min_delay: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let max_increase_value: u32 = max_increase.try_into().map_err(|_| revert("Max increase overflow"))?; + let min_delay: BlockNumberFor = min_delay.try_into().map_err(|_| revert("Min delay overflow"))?; + + let change_rate = pallet_tangle_lst::CommissionChangeRate { + max_increase: Perbill::from_parts(max_increase_value), + min_delay, + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_tangle_lst::Call::::set_commission_change_rate { + pool_id, + change_rate, + }, + )?; + + Ok(()) + } + + #[precompile::public("claimCommission(uint256)")] + fn claim_commission( + handle: &mut impl PrecompileHandle, + pool_id: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + RuntimeHelper::::try_dispatch( + handle, + Some(origin).into(), + pallet_tangle_lst::Call::::claim_commission { pool_id }, + )?; + + Ok(()) + } + + #[precompile::public("adjustPoolDeposit(uint256)")] + fn adjust_pool_deposit( + handle: &mut impl PrecompileHandle, + pool_id: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_tangle_lst::Call::::adjust_pool_deposit { + pool_id, + }, + )?; + + Ok(()) + } + + #[precompile::public("setCommissionClaimPermission(uint256,uint8)")] + fn set_commission_claim_permission( + handle: &mut impl PrecompileHandle, + pool_id: U256, + permission: u8, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let permission = match permission { + 0 => Some(pallet_tangle_lst::CommissionClaimPermission::Permissionless), + 1 => Some(pallet_tangle_lst::CommissionClaimPermission::Account( + Runtime::AddressMapping::into_account_id(handle.context().caller) + )), + _ => None, + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_tangle_lst::Call::::set_commission_claim_permission { + pool_id, + permission, + }, + )?; + + Ok(()) + } } impl TangleLstPrecompile From 90f86d17b5674de293c5027c37b410307c908466 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 21 Jan 2025 10:41:23 +0400 Subject: [PATCH 13/20] HAL-20 : add missing tangle lst precompiles --- precompiles/tangle-lst/src/lib.rs | 380 +++++++++++++++--------------- 1 file changed, 185 insertions(+), 195 deletions(-) diff --git a/precompiles/tangle-lst/src/lib.rs b/precompiles/tangle-lst/src/lib.rs index 53e734fbf..df36cbd8b 100644 --- a/precompiles/tangle-lst/src/lib.rs +++ b/precompiles/tangle-lst/src/lib.rs @@ -324,201 +324,191 @@ where Ok(()) } - #[precompile::public("chill(uint256)")] - fn chill(handle: &mut impl PrecompileHandle, pool_id: U256) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - - let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - - RuntimeHelper::::try_dispatch( - handle, - Some(origin).into(), - pallet_tangle_lst::Call::::chill { pool_id }, - )?; - - Ok(()) - } - - #[precompile::public("bondExtraOther(uint256,bytes32,uint256)")] - fn bond_extra_other( - handle: &mut impl PrecompileHandle, - pool_id: U256, - who: H256, - amount: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - - let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; - let member = Self::convert_to_account_id(who)?; - let extra = pallet_tangle_lst::BondExtra::FreeBalance( - amount.try_into().map_err(|_| revert("Amount overflow"))? - ); - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - - RuntimeHelper::::try_dispatch( - handle, - Some(origin).into(), - pallet_tangle_lst::Call::::bond_extra_other { - pool_id, - member: Runtime::Lookup::unlookup(member), - extra, - }, - )?; - - Ok(()) - } - - #[precompile::public("setCommission(uint256,uint256)")] - fn set_commission( - handle: &mut impl PrecompileHandle, - pool_id: U256, - new_commission: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - - let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; - let commission_value: u32 = new_commission.try_into().map_err(|_| revert("Commission overflow"))?; - let commission = if commission_value == 0 { - None - } else { - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - Some((Perbill::from_parts(commission_value), origin)) - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), - pallet_tangle_lst::Call::::set_commission { - pool_id, - new_commission: commission, - }, - )?; - - Ok(()) - } - - #[precompile::public("setCommissionMax(uint256,uint256)")] - fn set_commission_max( - handle: &mut impl PrecompileHandle, - pool_id: U256, - max_commission: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - - let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; - let max_commission_value: u32 = max_commission.try_into().map_err(|_| revert("Max commission overflow"))?; - let max_commission = Perbill::from_parts(max_commission_value); - - RuntimeHelper::::try_dispatch( - handle, - Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), - pallet_tangle_lst::Call::::set_commission_max { - pool_id, - max_commission, - }, - )?; - - Ok(()) - } - - #[precompile::public("setCommissionChangeRate(uint256,uint256,uint256)")] - fn set_commission_change_rate( - handle: &mut impl PrecompileHandle, - pool_id: U256, - max_increase: U256, - min_delay: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - - let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; - let max_increase_value: u32 = max_increase.try_into().map_err(|_| revert("Max increase overflow"))?; - let min_delay: BlockNumberFor = min_delay.try_into().map_err(|_| revert("Min delay overflow"))?; - - let change_rate = pallet_tangle_lst::CommissionChangeRate { - max_increase: Perbill::from_parts(max_increase_value), - min_delay, - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), - pallet_tangle_lst::Call::::set_commission_change_rate { - pool_id, - change_rate, - }, - )?; - - Ok(()) - } - - #[precompile::public("claimCommission(uint256)")] - fn claim_commission( - handle: &mut impl PrecompileHandle, - pool_id: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - - let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - - RuntimeHelper::::try_dispatch( - handle, - Some(origin).into(), - pallet_tangle_lst::Call::::claim_commission { pool_id }, - )?; - - Ok(()) - } - - #[precompile::public("adjustPoolDeposit(uint256)")] - fn adjust_pool_deposit( - handle: &mut impl PrecompileHandle, - pool_id: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - - let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; - - RuntimeHelper::::try_dispatch( - handle, - Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), - pallet_tangle_lst::Call::::adjust_pool_deposit { - pool_id, - }, - )?; - - Ok(()) - } - - #[precompile::public("setCommissionClaimPermission(uint256,uint8)")] - fn set_commission_claim_permission( - handle: &mut impl PrecompileHandle, - pool_id: U256, - permission: u8, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - - let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; - let permission = match permission { - 0 => Some(pallet_tangle_lst::CommissionClaimPermission::Permissionless), - 1 => Some(pallet_tangle_lst::CommissionClaimPermission::Account( - Runtime::AddressMapping::into_account_id(handle.context().caller) - )), - _ => None, - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), - pallet_tangle_lst::Call::::set_commission_claim_permission { - pool_id, - permission, - }, - )?; - - Ok(()) - } + #[precompile::public("chill(uint256)")] + fn chill(handle: &mut impl PrecompileHandle, pool_id: U256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + RuntimeHelper::::try_dispatch( + handle, + Some(origin).into(), + pallet_tangle_lst::Call::::chill { pool_id }, + )?; + + Ok(()) + } + + #[precompile::public("bondExtraOther(uint256,bytes32,uint256)")] + fn bond_extra_other( + handle: &mut impl PrecompileHandle, + pool_id: U256, + who: H256, + amount: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let member = Self::convert_to_account_id(who)?; + let extra = pallet_tangle_lst::BondExtra::FreeBalance( + amount.try_into().map_err(|_| revert("Amount overflow"))?, + ); + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + RuntimeHelper::::try_dispatch( + handle, + Some(origin).into(), + pallet_tangle_lst::Call::::bond_extra_other { + pool_id, + member: Runtime::Lookup::unlookup(member), + extra, + }, + )?; + + Ok(()) + } + + #[precompile::public("setCommission(uint256,uint256)")] + fn set_commission( + handle: &mut impl PrecompileHandle, + pool_id: U256, + new_commission: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let commission_value: u32 = + new_commission.try_into().map_err(|_| revert("Commission overflow"))?; + let commission = if commission_value == 0 { + None + } else { + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + Some((Perbill::from_parts(commission_value), origin)) + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_tangle_lst::Call::::set_commission { + pool_id, + new_commission: commission, + }, + )?; + + Ok(()) + } + + #[precompile::public("setCommissionMax(uint256,uint256)")] + fn set_commission_max( + handle: &mut impl PrecompileHandle, + pool_id: U256, + max_commission: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let max_commission_value: u32 = + max_commission.try_into().map_err(|_| revert("Max commission overflow"))?; + let max_commission = Perbill::from_parts(max_commission_value); + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_tangle_lst::Call::::set_commission_max { pool_id, max_commission }, + )?; + + Ok(()) + } + + #[precompile::public("setCommissionChangeRate(uint256,uint256,uint256)")] + fn set_commission_change_rate( + handle: &mut impl PrecompileHandle, + pool_id: U256, + max_increase: U256, + min_delay: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let max_increase_value: u32 = + max_increase.try_into().map_err(|_| revert("Max increase overflow"))?; + let min_delay: BlockNumberFor = + min_delay.try_into().map_err(|_| revert("Min delay overflow"))?; + + let change_rate = pallet_tangle_lst::CommissionChangeRate { + max_increase: Perbill::from_parts(max_increase_value), + min_delay, + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_tangle_lst::Call::::set_commission_change_rate { pool_id, change_rate }, + )?; + + Ok(()) + } + + #[precompile::public("claimCommission(uint256)")] + fn claim_commission(handle: &mut impl PrecompileHandle, pool_id: U256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + RuntimeHelper::::try_dispatch( + handle, + Some(origin).into(), + pallet_tangle_lst::Call::::claim_commission { pool_id }, + )?; + + Ok(()) + } + + #[precompile::public("adjustPoolDeposit(uint256)")] + fn adjust_pool_deposit(handle: &mut impl PrecompileHandle, pool_id: U256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_tangle_lst::Call::::adjust_pool_deposit { pool_id }, + )?; + + Ok(()) + } + + #[precompile::public("setCommissionClaimPermission(uint256,uint8)")] + fn set_commission_claim_permission( + handle: &mut impl PrecompileHandle, + pool_id: U256, + permission: u8, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let pool_id = pool_id.try_into().map_err(|_| revert("Pool ID overflow"))?; + let permission = match permission { + 0 => Some(pallet_tangle_lst::CommissionClaimPermission::Permissionless), + 1 => Some(pallet_tangle_lst::CommissionClaimPermission::Account( + Runtime::AddressMapping::into_account_id(handle.context().caller), + )), + _ => None, + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_tangle_lst::Call::::set_commission_claim_permission { + pool_id, + permission, + }, + )?; + + Ok(()) + } } impl TangleLstPrecompile From 4dec4d9d30adb0a8beba92b4b01af91a502ed714 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:04:49 +0400 Subject: [PATCH 14/20] HAL-20 : add missing staking precompiles --- precompiles/staking/StakingInterface.sol | 31 +++++ precompiles/staking/src/lib.rs | 139 ++++++++++++++++++++++- 2 files changed, 169 insertions(+), 1 deletion(-) diff --git a/precompiles/staking/StakingInterface.sol b/precompiles/staking/StakingInterface.sol index b18541cdb..b488141da 100644 --- a/precompiles/staking/StakingInterface.sol +++ b/precompiles/staking/StakingInterface.sol @@ -95,4 +95,35 @@ interface Staking { /// @dev Rebond a portion of the unbonded tokens. /// @param value Amount of tokens to rebond. function rebond(uint256 value) external; + + /// @dev Declare the desire to validate for the origin controller. + /// @param commission The commission as parts per billion. + function validate(uint256 commission) external; + + /// @dev Remove all staking-related data for a stash account. + /// @param stash The stash account to reap. + function reapStash(bytes32 stash) external; + + /// @dev Remove nominator status from multiple accounts. + /// @param who The accounts to kick. + function kick(bytes32[] calldata who) external; + + /// @dev Stop nominating or validating for another account. + /// @param controller The controller account to chill. + function chillOther(bytes32 controller) external; + + /// @dev Force a validator to have at least the minimum commission. + /// @param validatorStash The validator's stash account. + function forceApplyMinCommission(bytes32 validatorStash) external; + + /// @dev Pay out rewards for a validator and era by page. + /// @param validatorStash The validator's stash account. + /// @param era The era to pay out. + /// @param page The page number. + function payoutStakersByPage(bytes32 validatorStash, uint32 era, uint32 page) external; + + /// @dev Update the reward destination for a stash account. + /// @param stash The stash account. + /// @param payee The reward destination type (0-Staked, 1-Stash, 2-Account, 3-None). + function updatePayee(bytes32 stash, uint8 payee) external; } diff --git a/precompiles/staking/src/lib.rs b/precompiles/staking/src/lib.rs index 9c073ba46..f7259d830 100644 --- a/precompiles/staking/src/lib.rs +++ b/precompiles/staking/src/lib.rs @@ -47,7 +47,10 @@ use frame_support::{ use pallet_evm::AddressMapping; use precompile_utils::prelude::*; use sp_core::{H160, H256, U256}; -use sp_runtime::traits::{Dispatchable, StaticLookup}; +use sp_runtime::{ + traits::{Dispatchable, StaticLookup}, + Perbill, +}; use sp_std::{convert::TryInto, marker::PhantomData, vec, vec::Vec}; use tangle_primitives::types::WrappedAccountId32; @@ -112,6 +115,10 @@ where Ok(payee) } + + fn convert_to_account_id(account: H256) -> EvmResult { + Self::parse_32byte_address(account.0.to_vec()) + } } #[precompile_utils::precompile] @@ -397,4 +404,134 @@ where Ok(()) } + + #[precompile::public("validate(uint256)")] + fn validate(handle: &mut impl PrecompileHandle, commission: U256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let commission_value: u32 = + commission.try_into().map_err(|_| revert("Commission overflow"))?; + let prefs = pallet_staking::ValidatorPrefs { + commission: Perbill::from_parts(commission_value), + blocked: false, + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_staking::Call::::validate { prefs }, + )?; + + Ok(()) + } + + #[precompile::public("reapStash(bytes32)")] + fn reap_stash(handle: &mut impl PrecompileHandle, stash: H256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let stash = Self::convert_to_account_id(stash)?; + let num_slashing_spans = 0u32; // Default to 0 as it's the most common case + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_staking::Call::::reap_stash { stash, num_slashing_spans }, + )?; + + Ok(()) + } + + #[precompile::public("kick(bytes32[])")] + fn kick(handle: &mut impl PrecompileHandle, who: Vec) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let who: Vec = + who.into_iter().map(Self::convert_to_account_id).collect::>()?; + + let who = who.into_iter().map(|id| Runtime::Lookup::unlookup(id)).collect(); + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_staking::Call::::kick { who }, + )?; + + Ok(()) + } + + #[precompile::public("chillOther(bytes32)")] + fn chill_other(handle: &mut impl PrecompileHandle, controller: H256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let stash = Self::convert_to_account_id(controller)?; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_staking::Call::::chill_other { stash }, + )?; + + Ok(()) + } + + #[precompile::public("forceApplyMinCommission(bytes32)")] + fn force_apply_min_commission( + handle: &mut impl PrecompileHandle, + validator_stash: H256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let validator_stash = Self::convert_to_account_id(validator_stash)?; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_staking::Call::::force_apply_min_commission { validator_stash }, + )?; + + Ok(()) + } + + #[precompile::public("payoutStakersByPage(bytes32,uint32,uint32)")] + fn payout_stakers_by_page( + handle: &mut impl PrecompileHandle, + validator_stash: H256, + era: u32, + page: u32, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let validator_stash = Self::convert_to_account_id(validator_stash)?; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_staking::Call::::payout_stakers_by_page { validator_stash, era, page }, + )?; + + Ok(()) + } + + #[precompile::public("updatePayee(bytes32,uint8)")] + fn update_payee(handle: &mut impl PrecompileHandle, stash: H256, payee: u8) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let controller = Self::convert_to_account_id(stash)?; + let reward_destination = match payee { + 0 => pallet_staking::RewardDestination::Staked, + 1 => pallet_staking::RewardDestination::Stash, + 2 => pallet_staking::RewardDestination::Controller, + 3 => pallet_staking::RewardDestination::Account(controller.clone()), + 4 => pallet_staking::RewardDestination::None, + _ => return Err(revert("Invalid reward destination")), + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(Runtime::AddressMapping::into_account_id(handle.context().caller)).into(), + pallet_staking::Call::::set_payee { payee: reward_destination }, + )?; + + Ok(()) + } } From 2f8bd7a8062097461f946e664365d5fa1d6dc861 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:09:50 +0400 Subject: [PATCH 15/20] fix fuzzer --- .../multi-asset-delegation/fuzzer/call.rs | 74 +++++++++---------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/precompiles/multi-asset-delegation/fuzzer/call.rs b/precompiles/multi-asset-delegation/fuzzer/call.rs index f98d75b4e..281d27ca5 100644 --- a/precompiles/multi-asset-delegation/fuzzer/call.rs +++ b/precompiles/multi-asset-delegation/fuzzer/call.rs @@ -21,7 +21,6 @@ //! # Debugging a panic //! Once a panic is found, it can be debugged with //! `cargo hfuzz run-debug mad-fuzzer hfuzz_workspace/mad-fuzzer/*.fuzz`. - use fp_evm::Context; use fp_evm::PrecompileSet; use frame_support::traits::{Currency, Get}; @@ -39,6 +38,7 @@ use precompile_utils::prelude::*; use precompile_utils::testing::*; use rand::{seq::SliceRandom, Rng}; use sp_runtime::traits::{Scale, Zero}; +use sp_runtime::DispatchResult; const MAX_ED_MULTIPLE: Balance = 10_000; const MIN_ED_MULTIPLE: Balance = 10; @@ -82,13 +82,13 @@ fn fund_account(rng: &mut R, address: &Address) { } /// Join operators call. -fn join_operators_call(rng: &mut R, who: &Address) -> (PCall, Address) { +fn join_operators(rng: &mut R, who: &Address) -> DispatchResult { let minimum_bond = <::MinOperatorBondAmount as Get>::get(); let multiplier = rng.gen_range(1..50u64); let who_account_id = >::into_account_id(who.0); let _ = Balances::deposit_creating(&who_account_id, minimum_bond.mul(multiplier)); let bond_amount = minimum_bond.mul(multiplier).into(); - (PCall::join_operators { bond_amount }, *who) + MultiAssetDelegation::join_operators(RuntimeOrigin::signed(who_account_id), bond_amount) } fn random_calls(mut rng: &mut R) -> impl IntoIterator { @@ -147,19 +147,17 @@ fn random_calls(mut rng: &mut R) -> impl IntoIterator()).collect::>() }; - vec![ - join_operators_call(&mut rng, &operator), - ( - PCall::delegate { - operator: operator.0.into(), - asset_id, - token_address, - amount, - blueprint_selection, - }, - who, - ), - ] + join_operators(&mut rng, &operator).unwrap(); + vec![( + PCall::delegate { + operator: operator.0.into(), + asset_id, + token_address, + amount, + blueprint_selection, + }, + who, + )] }, _ if op == PCall::schedule_delegator_unstake_selectors()[0] => { // Schedule delegator unstakes @@ -171,18 +169,16 @@ fn random_calls(mut rng: &mut R) -> impl IntoIterator (0.into(), token.into()), }; let amount = random_ed_multiple(&mut rng).into(); - vec![ - join_operators_call(&mut rng, &operator), - ( - PCall::schedule_delegator_unstake { - operator: operator.0.into(), - asset_id, - token_address, - amount, - }, - who, - ), - ] + join_operators(&mut rng, &operator).unwrap(); + vec![( + PCall::schedule_delegator_unstake { + operator: operator.0.into(), + asset_id, + token_address, + amount, + }, + who, + )] }, _ if op == PCall::execute_delegator_unstake_selectors()[0] => { // Execute delegator unstake @@ -200,18 +196,16 @@ fn random_calls(mut rng: &mut R) -> impl IntoIterator (0.into(), token.into()), }; let amount = random_ed_multiple(&mut rng).into(); - vec![ - join_operators_call(&mut rng, &operator), - ( - PCall::cancel_delegator_unstake { - operator: operator.0.into(), - asset_id, - token_address, - amount, - }, - who, - ), - ] + join_operators(&mut rng, &operator).unwrap(); + vec![( + PCall::cancel_delegator_unstake { + operator: operator.0.into(), + asset_id, + token_address, + amount, + }, + who, + )] }, _ => { unimplemented!("unknown call name: {}", op) From d68ec0ae94b27ca53bbead598f285cefee095ac9 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:29:26 +0400 Subject: [PATCH 16/20] HAL-20 : add missing services precompile --- precompiles/services/Services.sol | 221 ++++++++++++++---------------- precompiles/services/src/lib.rs | 50 ++++++- 2 files changed, 154 insertions(+), 117 deletions(-) diff --git a/precompiles/services/Services.sol b/precompiles/services/Services.sol index cc5714369..8950e545f 100644 --- a/precompiles/services/Services.sol +++ b/precompiles/services/Services.sol @@ -1,117 +1,106 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.0; - -/// @title ServicesPrecompile Interface -/// @dev This interface is meant to interact with the ServicesPrecompile in the Tangle network. -interface ServicesPrecompile { - /// @dev Invalid Permitted Callers provided - error InvalidPermittedCallers(); - /// @dev Invalid Service Providers provided - error InvalidOperatorsList(); - /// @dev Invalid Request Arguments provided - error InvalidRequestArguments(); - /// @dev Invalid TTL Value provided - error InvalidTTL(); - /// @dev Invalid Payment Amount provided - error InvalidAmount(); - /// @dev `msg.value` must be zero when using ERC20 token for payment - error ValueMustBeZeroForERC20(); - /// @dev `msg.value` must be zero when using custom asset for payment - error ValueMustBeZeroForCustomAsset(); - /// @dev Payment asset should be either custom or ERC20 - error PaymentAssetShouldBeCustomOrERC20(); - - /// @notice Create a new service blueprint - /// @param blueprint_data The blueprint data encoded as bytes - function createBlueprint(bytes calldata blueprint_data) external; - - /// @notice Register an operator for a specific blueprint - /// @param blueprint_id The ID of the blueprint to register for - /// @param preferences The operator's preferences encoded as bytes - /// @param registration_args The registration arguments encoded as bytes - function registerOperator( - uint256 blueprint_id, - bytes calldata preferences, - bytes calldata registration_args - ) external payable; - - /// @notice Unregister an operator from a specific blueprint - /// @param blueprint_id The ID of the blueprint to unregister from - function unregisterOperator(uint256 blueprint_id) external; - - /// @notice Request a service from a specific blueprint - /// @param blueprint_id The ID of the blueprint - /// @param assets The list of assets to use for the service - /// @param permitted_callers_data The permitted callers for the service encoded as bytes - /// @param service_providers_data The service providers encoded as bytes - /// @param request_args_data The request arguments encoded as bytes - /// @param ttl The time-to-live of the service. - /// @param payment_asset_id The ID of the asset to use for payment (0 for native asset) - /// @param payment_token_address The address of the token to use for payment (0x0 for using the value of payment_asset_id) - /// @param payment_amount The amount to pay for the service (use msg.value if payment_asset_id is 0) - function requestService( - uint256 blueprint_id, - uint256[] calldata assets, - bytes calldata permitted_callers_data, - bytes calldata service_providers_data, - bytes calldata request_args_data, - uint256 ttl, - uint256 payment_asset_id, - address payment_token_address, - uint256 payment_amount - ) external payable; - - /// @notice Terminate a service - /// @param service_id The ID of the service to terminate - function terminateService(uint256 service_id) external; - - /// @notice Approve a service request - /// @param request_id The ID of the service request to approve - /// @param restaking_percent The amount of your restake to be exposed to the service in percentage [0, 100] - function approve(uint256 request_id, uint8 restaking_percent) external; - - /// @notice Reject a service request - /// @param request_id The ID of the service request to reject - function reject(uint256 request_id) external; - - /// @notice Call a job in the service - /// @param service_id The ID of the service - /// @param job The job index (as uint8) - /// @param args_data The arguments of the job encoded as bytes - function callJob( - uint256 service_id, - uint8 job, - bytes calldata args_data - ) external; - - /// @notice Submit the result of a job call - /// @param service_id The ID of the service - /// @param call_id The ID of the call - /// @param result_data The result data encoded as bytes - function submitResult( - uint256 service_id, - uint256 call_id, - bytes calldata result_data - ) external; - - /// @notice Slash an operator (offender) for a service id with a given percent of their exposed stake for that service. - /// - /// The caller needs to be an authorized Slash Origin for this service. - /// Note that this does not apply the slash directly, but instead schedules a deferred call to apply the slash - /// by another entity. - /// @param offender The operator to be slashed encoded as bytes - /// @param service_id The ID of the service to slash for - /// @param percent The percent of the offender's exposed stake to slash - function slash( - bytes calldata offender, - uint256 service_id, - uint8 percent - ) external; - - /// @notice Dispute an Unapplied Slash for a service id. - /// - /// The caller needs to be an authorized Dispute Origin for this service. - /// @param era The era of the unapplied slash. - /// @param slash_index The index of the unapplied slash in the era. - function dispute(uint32 era, uint32 slash_index) external; +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity >=0.8.3; + +/// @dev The Services contract's address. +address constant SERVICES_ADDRESS = 0x0000000000000000000000000000000000000900; + +/// @dev The Services contract's instance. +Services constant SERVICES_CONTRACT = Services(SERVICES_ADDRESS); + +/// @title Pallet Services Interface +/// @dev The interface through which solidity contracts will interact with Services pallet +/// We follow this same interface including four-byte function selectors, in the precompile that +/// wraps the pallet +/// @custom:address 0x0000000000000000000000000000000000000900 +interface Services { + /// @dev Create a new blueprint. + /// @param blueprint_data The blueprint data in SCALE-encoded format. + function createBlueprint(bytes calldata blueprint_data) external; + + /// @dev Register as an operator for a specific blueprint. + /// @param blueprint_id The blueprint ID. + /// @param preferences The operator preferences in SCALE-encoded format. + /// @param registration_args The registration arguments in SCALE-encoded format. + function registerOperator(uint256 blueprint_id, bytes calldata preferences, bytes calldata registration_args) external payable; + + /// @dev Pre-register as an operator for a specific blueprint. + /// @param blueprint_id The blueprint ID. + function preRegister(uint256 blueprint_id) external; + + /// @dev Unregister as an operator from a blueprint. + /// @param blueprint_id The blueprint ID. + function unregisterOperator(uint256 blueprint_id) external; + + /// @dev Request a new service. + /// @param blueprint_id The blueprint ID. + /// @param assets The list of asset IDs. + /// @param permitted_callers The permitted callers in SCALE-encoded format. + /// @param service_providers The service providers in SCALE-encoded format. + /// @param request_args The request arguments in SCALE-encoded format. + /// @param ttl The time-to-live for the request. + /// @param payment_asset_id The payment asset ID. + /// @param payment_token_address The payment token address. + /// @param amount The payment amount. + function requestService( + uint256 blueprint_id, + uint256[] calldata assets, + bytes calldata permitted_callers, + bytes calldata service_providers, + bytes calldata request_args, + uint256 ttl, + uint256 payment_asset_id, + address payment_token_address, + uint256 amount + ) external payable; + + /// @dev Terminate a service. + /// @param service_id The service ID. + function terminateService(uint256 service_id) external; + + /// @dev Approve a request. + /// @param request_id The request ID. + /// @param restaking_percent The restaking percentage. + function approve(uint256 request_id, uint8 restaking_percent) external; + + /// @dev Reject a service request. + /// @param request_id The request ID. + function reject(uint256 request_id) external; + + /// @dev Call a job in the service. + /// @param service_id The service ID. + /// @param job The job ID. + /// @param args_data The job arguments in SCALE-encoded format. + function callJob(uint256 service_id, uint8 job, bytes calldata args_data) external; + + /// @dev Submit the result for a job call. + /// @param service_id The service ID. + /// @param call_id The call ID. + /// @param result_data The result data in SCALE-encoded format. + function submitResult(uint256 service_id, uint256 call_id, bytes calldata result_data) external; + + /// @dev Slash an operator for a service. + /// @param offender The offender in SCALE-encoded format. + /// @param service_id The service ID. + /// @param percent The slash percentage. + function slash(bytes calldata offender, uint256 service_id, uint8 percent) external; + + /// @dev Dispute an unapplied slash. + /// @param era The era number. + /// @param index The index of the slash. + function dispute(uint32 era, uint32 index) external; + + /// @dev Update price targets for a blueprint. + /// @param blueprint_id The blueprint ID. + /// @param price_targets The new price targets. + function updatePriceTargets(uint256 blueprint_id, uint256[] calldata price_targets) external; + + /// @dev Custom errors for the Services precompile + error InvalidPermittedCallers(); + error InvalidOperatorsList(); + error InvalidRequestArguments(); + error InvalidTTL(); + error InvalidAmount(); + error ValueMustBeZeroForERC20(); + error ValueMustBeZeroForCustomAsset(); + error PaymentAssetShouldBeCustomOrERC20(); } diff --git a/precompiles/services/src/lib.rs b/precompiles/services/src/lib.rs index b7a3bc9ff..f18b77a80 100644 --- a/precompiles/services/src/lib.rs +++ b/precompiles/services/src/lib.rs @@ -11,7 +11,9 @@ use precompile_utils::prelude::*; use sp_core::U256; use sp_runtime::{traits::Dispatchable, Percent}; use sp_std::{marker::PhantomData, vec::Vec}; -use tangle_primitives::services::{Asset, Field, OperatorPreferences, ServiceBlueprint}; +use tangle_primitives::services::{ + Asset, Field, OperatorPreferences, PriceTargets, ServiceBlueprint, +}; #[cfg(test)] mod mock; @@ -382,6 +384,52 @@ where Ok(()) } + + /// Update price targets for a blueprint. + #[precompile::public("updatePriceTargets(uint256,uint256[])")] + fn update_price_targets( + handle: &mut impl PrecompileHandle, + blueprint_id: U256, + price_targets: Vec, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let blueprint_id: u64 = blueprint_id.as_u64(); + + // Convert price targets into the correct struct + let price_targets = { + let mut targets = price_targets.into_iter(); + PriceTargets { + cpu: targets.next().map_or(0, |v| v.as_u64()), + mem: targets.next().map_or(0, |v| v.as_u64()), + storage_hdd: targets.next().map_or(0, |v| v.as_u64()), + storage_ssd: targets.next().map_or(0, |v| v.as_u64()), + storage_nvme: targets.next().map_or(0, |v| v.as_u64()), + } + }; + + let call = + pallet_services::Call::::update_price_targets { blueprint_id, price_targets }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + /// Pre-register as an operator for a specific blueprint. + #[precompile::public("preRegister(uint256)")] + fn pre_register(handle: &mut impl PrecompileHandle, blueprint_id: U256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let blueprint_id: u64 = blueprint_id.as_u64(); + let call = pallet_services::Call::::pre_register { blueprint_id }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } } /// Revert with Custom Error Selector From 921e96925043f621c84f9cefb064932ce6cc5a5a Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 21 Jan 2025 15:09:33 +0400 Subject: [PATCH 17/20] fix integration test --- node/tests/evm_restaking.rs | 42 +++++++++++-------- .../multi-asset-delegation/src/tests.rs | 2 +- precompiles/staking/src/lib.rs | 1 - 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/node/tests/evm_restaking.rs b/node/tests/evm_restaking.rs index 187dcc967..f36f96d4b 100644 --- a/node/tests/evm_restaking.rs +++ b/node/tests/evm_restaking.rs @@ -380,26 +380,35 @@ pub struct TestInputs { } /// Helper function for joining as an operator -async fn join_as_operator(provider: &AlloyProviderWithWallet, stake: U256) -> anyhow::Result { - let precompile = MultiAssetDelegation::new(MULTI_ASSET_DELEGATION, provider); - let result = precompile - .joinOperators(stake) - .send() - .await? - .with_timeout(Some(Duration::from_secs(5))) - .get_receipt() - .await?; - Ok(result.status()) +async fn join_as_operator( + client: &subxt::OnlineClient, + caller: tangle_subxt::subxt_signer::sr25519::Keypair, + stake: u128, +) -> anyhow::Result { + let join_call = api::tx().multi_asset_delegation().join_operators(stake); + let mut result = client.tx().sign_and_submit_then_watch_default(&join_call, &caller).await?; + while let Some(Ok(s)) = result.next().await { + if let TxStatus::InBestBlock(b) = s { + let _evs = match b.wait_for_success().await { + Ok(evs) => evs, + Err(e) => { + error!("Error: {:?}", e); + break; + }, + }; + break; + } + } + Ok(true) } #[test] fn operator_join_delegator_delegate_erc20() { run_mad_test(|t| async move { let alice = TestAccount::Alice; - let alice_provider = alloy_provider_with_wallet(&t.provider, alice.evm_wallet()); // Join operators let tnt = U256::from(100_000u128); - assert!(join_as_operator(&alice_provider, tnt).await?); + assert!(join_as_operator(&t.subxt, alice.substrate_signer(), tnt.to::()).await?); let operator_key = api::storage() .multi_asset_delegation() @@ -472,11 +481,9 @@ fn operator_join_delegator_delegate_erc20() { fn operator_join_delegator_delegate_asset_id() { run_mad_test(|t| async move { let alice = TestAccount::Alice; - let alice_provider = alloy_provider_with_wallet(&t.provider, alice.evm_wallet()); - // Join operators let tnt = U256::from(100_000u128); - assert!(join_as_operator(&alice_provider, tnt).await?); + assert!(join_as_operator(&t.subxt, alice.substrate_signer(), tnt.to::()).await?); let operator_key = api::storage() .multi_asset_delegation() @@ -736,7 +743,7 @@ fn lrt_deposit_withdraw_erc20() { let alice_provider = alloy_provider_with_wallet(&t.provider, alice.evm_wallet()); // Join operators let tnt = U256::from(100_000u128); - assert!(join_as_operator(&alice_provider, tnt).await?); + assert!(join_as_operator(&t.subxt, alice.substrate_signer(), tnt.to::()).await?); // Setup a LRT Vault for Alice. let lrt_address = deploy_tangle_lrt( alice_provider.clone(), @@ -889,7 +896,8 @@ fn lrt_rewards() { let alice_provider = alloy_provider_with_wallet(&t.provider, alice.evm_wallet()); // Join operators let tnt = U256::from(100_000u128); - assert!(join_as_operator(&alice_provider, tnt).await?); + assert!(join_as_operator(&t.subxt, alice.substrate_signer(), tnt.to::()).await?); + // Setup a LRT Vault for Alice. let lrt_address = deploy_tangle_lrt( alice_provider.clone(), diff --git a/precompiles/multi-asset-delegation/src/tests.rs b/precompiles/multi-asset-delegation/src/tests.rs index 969c902fa..e62330447 100644 --- a/precompiles/multi-asset-delegation/src/tests.rs +++ b/precompiles/multi-asset-delegation/src/tests.rs @@ -1,6 +1,6 @@ use crate::{mock::*, mock_evm::*, U256}; use frame_support::{assert_ok, traits::Currency}; -use pallet_multi_asset_delegation::{types::OperatorStatus, CurrentRound, Delegators, Operators}; +use pallet_multi_asset_delegation::{CurrentRound, Delegators, Operators}; use precompile_utils::prelude::*; use precompile_utils::testing::*; use sp_core::H160; diff --git a/precompiles/staking/src/lib.rs b/precompiles/staking/src/lib.rs index f7259d830..21596bbd7 100644 --- a/precompiles/staking/src/lib.rs +++ b/precompiles/staking/src/lib.rs @@ -520,7 +520,6 @@ where let reward_destination = match payee { 0 => pallet_staking::RewardDestination::Staked, 1 => pallet_staking::RewardDestination::Stash, - 2 => pallet_staking::RewardDestination::Controller, 3 => pallet_staking::RewardDestination::Account(controller.clone()), 4 => pallet_staking::RewardDestination::None, _ => return Err(revert("Invalid reward destination")), From 97a4e2af2d09bb99e73043eb14dc4d388c0cb4fc Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 21 Jan 2025 15:39:01 +0400 Subject: [PATCH 18/20] HAL-20 : add vesting precompile --- .../src/types/delegator.rs | 2 +- .../multi-asset-delegation/fuzzer/call.rs | 4 ++-- .../multi-asset-delegation/src/tests.rs | 2 +- precompiles/staking/src/lib.rs | 19 ++++++------------- precompiles/vesting/Vesting.sol | 5 +++++ precompiles/vesting/src/lib.rs | 18 ++++++++++++++++++ 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index f65fda38b..84aaaabd7 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -193,7 +193,7 @@ impl< let mut total = Balance::default(); for stake in &self.delegations { if stake.asset_id == asset_id { - total = total.checked_add(&stake.amount).unwrap_or_else(|| total); + total = total.checked_add(&stake.amount).unwrap_or(total); } } total diff --git a/precompiles/multi-asset-delegation/fuzzer/call.rs b/precompiles/multi-asset-delegation/fuzzer/call.rs index 281d27ca5..7be9919e3 100644 --- a/precompiles/multi-asset-delegation/fuzzer/call.rs +++ b/precompiles/multi-asset-delegation/fuzzer/call.rs @@ -37,7 +37,7 @@ use pallet_multi_asset_delegation::{ use precompile_utils::prelude::*; use precompile_utils::testing::*; use rand::{seq::SliceRandom, Rng}; -use sp_runtime::traits::{Scale, Zero}; +use sp_runtime::traits::Scale; use sp_runtime::DispatchResult; const MAX_ED_MULTIPLE: Balance = 10_000; @@ -87,7 +87,7 @@ fn join_operators(rng: &mut R, who: &Address) -> DispatchResult { let multiplier = rng.gen_range(1..50u64); let who_account_id = >::into_account_id(who.0); let _ = Balances::deposit_creating(&who_account_id, minimum_bond.mul(multiplier)); - let bond_amount = minimum_bond.mul(multiplier).into(); + let bond_amount = minimum_bond.mul(multiplier); MultiAssetDelegation::join_operators(RuntimeOrigin::signed(who_account_id), bond_amount) } diff --git a/precompiles/multi-asset-delegation/src/tests.rs b/precompiles/multi-asset-delegation/src/tests.rs index e62330447..d228be74f 100644 --- a/precompiles/multi-asset-delegation/src/tests.rs +++ b/precompiles/multi-asset-delegation/src/tests.rs @@ -263,7 +263,7 @@ fn test_delegate_assets_insufficient_balance() { token_address: Default::default(), }, ) - .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 6, error: [15, 0, 0, 0], message: Some(\"InsufficientBalance\") })"); + .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 6, error: [14, 0, 0, 0], message: Some(\"InsufficientBalance\") })"); assert_eq!(Balances::free_balance(delegator_account), 500); }); diff --git a/precompiles/staking/src/lib.rs b/precompiles/staking/src/lib.rs index 21596bbd7..cd2416859 100644 --- a/precompiles/staking/src/lib.rs +++ b/precompiles/staking/src/lib.rs @@ -146,9 +146,7 @@ where #[precompile::view] fn min_nominator_bond(handle: &mut impl PrecompileHandle) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let min_nominator_bond: U256 = pallet_staking::MinNominatorBond::::get() - .try_into() - .map_err(|_| revert("Amount is too large for provided balance type"))?; + let min_nominator_bond: U256 = pallet_staking::MinNominatorBond::::get().into(); Ok(min_nominator_bond) } @@ -157,9 +155,7 @@ where #[precompile::view] fn min_validator_bond(handle: &mut impl PrecompileHandle) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let min_validator_bond: U256 = pallet_staking::MinValidatorBond::::get() - .try_into() - .map_err(|_| revert("Amount is too large for provided balance type"))?; + let min_validator_bond: U256 = pallet_staking::MinValidatorBond::::get().into(); Ok(min_validator_bond) } @@ -168,9 +164,7 @@ where #[precompile::view] fn min_active_stake(handle: &mut impl PrecompileHandle) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let min_active_stake: U256 = pallet_staking::MinimumActiveStake::::get() - .try_into() - .map_err(|_| revert("Amount is too large for provided balance type"))?; + let min_active_stake: U256 = pallet_staking::MinimumActiveStake::::get().into(); Ok(min_active_stake) } @@ -218,9 +212,8 @@ where #[precompile::view] fn eras_total_stake(handle: &mut impl PrecompileHandle, era_index: u32) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let total_stake: U256 = >::eras_total_stake(era_index) - .try_into() - .map_err(|_| revert("Amount is too large for provided balance type"))?; + let total_stake: U256 = + >::eras_total_stake(era_index).into(); Ok(total_stake) } @@ -448,7 +441,7 @@ where let who: Vec = who.into_iter().map(Self::convert_to_account_id).collect::>()?; - let who = who.into_iter().map(|id| Runtime::Lookup::unlookup(id)).collect(); + let who = who.into_iter().map(Runtime::Lookup::unlookup).collect(); RuntimeHelper::::try_dispatch( handle, diff --git a/precompiles/vesting/Vesting.sol b/precompiles/vesting/Vesting.sol index 50fa357d5..83b2503db 100644 --- a/precompiles/vesting/Vesting.sol +++ b/precompiles/vesting/Vesting.sol @@ -23,4 +23,9 @@ interface Vesting { /// @param target The address of the account to transfer funds to. /// @param index The index of the vesting schedule to transfer. function vestedTransfer(bytes32 target, uint8 index) external returns (uint8); + + /// @dev Merge two vesting schedules together. + /// @param schedule1Index The index of the first vesting schedule. + /// @param schedule2Index The index of the second vesting schedule. + function mergeSchedules(uint32 schedule1Index, uint32 schedule2Index) external returns (uint8); } diff --git a/precompiles/vesting/src/lib.rs b/precompiles/vesting/src/lib.rs index 9c6133492..c1e68e940 100644 --- a/precompiles/vesting/src/lib.rs +++ b/precompiles/vesting/src/lib.rs @@ -172,4 +172,22 @@ where None => Err(revert("No vesting schedule found for the sender")), } } + + #[precompile::public("mergeSchedules(uint32,uint32)")] + fn merge_schedules( + handle: &mut impl PrecompileHandle, + schedule1_index: u32, + schedule2_index: u32, + ) -> EvmResult { + let caller = handle.context().caller; + let caller_account = Runtime::AddressMapping::into_account_id(caller); + + // Construct the call + let call = + pallet_vesting::Call::::merge_schedules { schedule1_index, schedule2_index }; + + RuntimeHelper::::try_dispatch(handle, Some(caller_account).into(), call)?; + + Ok(()) + } } From f5183bcdf9c466eb8d8b9fcab9d9aa22d84dc7c2 Mon Sep 17 00:00:00 2001 From: Shady Khalifa Date: Tue, 21 Jan 2025 14:50:50 +0200 Subject: [PATCH 19/20] fix: operator_join_delegator_delegate_erc20 test --- node/tests/evm_restaking.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/node/tests/evm_restaking.rs b/node/tests/evm_restaking.rs index f36f96d4b..56fa67a5b 100644 --- a/node/tests/evm_restaking.rs +++ b/node/tests/evm_restaking.rs @@ -410,9 +410,7 @@ fn operator_join_delegator_delegate_erc20() { let tnt = U256::from(100_000u128); assert!(join_as_operator(&t.subxt, alice.substrate_signer(), tnt.to::()).await?); - let operator_key = api::storage() - .multi_asset_delegation() - .operators(alice.address().to_account_id()); + let operator_key = api::storage().multi_asset_delegation().operators(alice.account_id()); let maybe_operator = t.subxt.storage().at_latest().await?.fetch(&operator_key).await?; assert!(maybe_operator.is_some()); assert_eq!(maybe_operator.map(|p| p.stake), Some(tnt.to::())); @@ -446,7 +444,7 @@ fn operator_join_delegator_delegate_erc20() { let delegate_result = precompile .delegate( - alice.address().to_account_id().0.into(), + alice.account_id().0.into(), U256::ZERO, *usdc.address(), delegate_amount, From 02fdcf2d238a6ed7f4fbab83684edf7fb07338f2 Mon Sep 17 00:00:00 2001 From: Shady Khalifa Date: Tue, 21 Jan 2025 15:11:33 +0200 Subject: [PATCH 20/20] fix: failing e2e tests --- node/tests/evm_restaking.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/node/tests/evm_restaking.rs b/node/tests/evm_restaking.rs index 56fa67a5b..57bf7aa20 100644 --- a/node/tests/evm_restaking.rs +++ b/node/tests/evm_restaking.rs @@ -483,9 +483,7 @@ fn operator_join_delegator_delegate_asset_id() { let tnt = U256::from(100_000u128); assert!(join_as_operator(&t.subxt, alice.substrate_signer(), tnt.to::()).await?); - let operator_key = api::storage() - .multi_asset_delegation() - .operators(alice.address().to_account_id()); + let operator_key = api::storage().multi_asset_delegation().operators(alice.account_id()); let maybe_operator = t.subxt.storage().at_latest().await?.fetch(&operator_key).await?; assert!(maybe_operator.is_some()); assert_eq!(maybe_operator.map(|p| p.stake), Some(tnt.to::())); @@ -541,7 +539,7 @@ fn operator_join_delegator_delegate_asset_id() { let delegate_result = precompile .delegate( - alice.address().to_account_id().0.into(), + alice.account_id().0.into(), U256::from(t.usdc_asset_id), Address::ZERO, U256::from(delegate_amount), @@ -746,7 +744,7 @@ fn lrt_deposit_withdraw_erc20() { let lrt_address = deploy_tangle_lrt( alice_provider.clone(), t.weth, - alice.address().to_account_id().0, + alice.account_id().0, "Liquid Restaked Ether", "lrtETH", ) @@ -794,9 +792,7 @@ fn lrt_deposit_withdraw_erc20() { assert_eq!(mad_weth_balance._0, deposit_amount); // LRT should be a delegator to the operator in the MAD pallet. - let operator_key = api::storage() - .multi_asset_delegation() - .operators(alice.address().to_account_id()); + let operator_key = api::storage().multi_asset_delegation().operators(alice.account_id()); let maybe_operator = t.subxt.storage().at_latest().await?.fetch(&operator_key).await?; assert!(maybe_operator.is_some()); assert_eq!(maybe_operator.as_ref().map(|p| p.delegation_count), Some(1)); @@ -900,7 +896,7 @@ fn lrt_rewards() { let lrt_address = deploy_tangle_lrt( alice_provider.clone(), t.weth, - alice.address().to_account_id().0, + alice.account_id().0, "Liquid Restaked Ether", "lrtETH", )