difftreelog
fix PR
in: master
4 files changed
pallets/fungible/src/erc.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is disaddress: tod in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! ERC-20 standart support implementation.1819extern crate alloc;20use core::char::{REPLACEMENT_CHARACTER, decode_utf16};21use core::convert::TryInto;22use evm_coder::AbiCoder;23use evm_coder::{24 abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,25 weight,26};27use up_data_structs::CollectionMode;28use pallet_common::{29 CollectionHandle,30 erc::{CommonEvmHandler, PrecompileResult, CollectionCall},31};32use sp_std::vec::Vec;33use pallet_evm::{account::CrossAccountId, PrecompileHandle};34use pallet_evm_coder_substrate::{call, dispatch_to_evm};35use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};36use sp_core::{U256, Get};3738use crate::{39 Allowance, Balance, Config, FungibleHandle, Pallet, SelfWeightOf, TotalSupply,40 weights::WeightInfo,41};4243#[derive(ToLog)]44pub enum ERC20Events {45 Transfer {46 #[indexed]47 from: Address,48 #[indexed]49 to: Address,50 value: U256,51 },52 Approval {53 #[indexed]54 owner: Address,55 #[indexed]56 spender: Address,57 value: U256,58 },59}6061#[derive(AbiCoder, Debug)]62pub struct AmountForAddress {63 to: Address,64 amount: U256,65}6667#[solidity_interface(name = ERC20, events(ERC20Events), expect_selector = 0x942e8b22)]68impl<T: Config> FungibleHandle<T> {69 fn name(&self) -> Result<String> {70 Ok(decode_utf16(self.name.iter().copied())71 .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))72 .collect::<String>())73 }74 fn symbol(&self) -> Result<String> {75 Ok(String::from_utf8_lossy(&self.token_prefix).into())76 }77 fn total_supply(&self) -> Result<U256> {78 self.consume_store_reads(1)?;79 Ok(<TotalSupply<T>>::get(self.id).into())80 }8182 fn decimals(&self) -> Result<u8> {83 Ok(if let CollectionMode::Fungible(decimals) = &self.mode {84 *decimals85 } else {86 unreachable!()87 })88 }89 fn balance_of(&self, owner: Address) -> Result<U256> {90 self.consume_store_reads(1)?;91 let owner = T::CrossAccountId::from_eth(owner);92 let balance = <Balance<T>>::get((self.id, owner));93 Ok(balance.into())94 }95 #[weight(<SelfWeightOf<T>>::transfer())]96 fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {97 let caller = T::CrossAccountId::from_eth(caller);98 let to = T::CrossAccountId::from_eth(to);99 let amount = amount.try_into().map_err(|_| "amount overflow")?;100 let budget = self101 .recorder102 .weight_calls_budget(<StructureWeight<T>>::find_parent());103104 <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;105 Ok(true)106 }107108 #[weight(<SelfWeightOf<T>>::transfer_from())]109 fn transfer_from(110 &mut self,111 caller: Caller,112 from: Address,113 to: Address,114 amount: U256,115 ) -> Result<bool> {116 let caller = T::CrossAccountId::from_eth(caller);117 let from = T::CrossAccountId::from_eth(from);118 let to = T::CrossAccountId::from_eth(to);119 let amount = amount.try_into().map_err(|_| "amount overflow")?;120 let budget = self121 .recorder122 .weight_calls_budget(<StructureWeight<T>>::find_parent());123124 <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)125 .map_err(dispatch_to_evm::<T>)?;126 Ok(true)127 }128 #[weight(<SelfWeightOf<T>>::approve())]129 fn approve(&mut self, caller: Caller, spender: Address, amount: U256) -> Result<bool> {130 let caller = T::CrossAccountId::from_eth(caller);131 let spender = T::CrossAccountId::from_eth(spender);132 let amount = amount.try_into().map_err(|_| "amount overflow")?;133134 <Pallet<T>>::set_allowance(self, &caller, &spender, amount)135 .map_err(dispatch_to_evm::<T>)?;136 Ok(true)137 }138 fn allowance(&self, owner: Address, spender: Address) -> Result<U256> {139 self.consume_store_reads(1)?;140 let owner = T::CrossAccountId::from_eth(owner);141 let spender = T::CrossAccountId::from_eth(spender);142143 Ok(<Allowance<T>>::get((self.id, owner, spender)).into())144 }145}146147#[solidity_interface(name = ERC20Mintable)]148impl<T: Config> FungibleHandle<T> {149 /// Mint tokens for `to` account.150 /// @param to account that will receive minted tokens151 /// @param amount amount of tokens to mint152 #[weight(<SelfWeightOf<T>>::create_item())]153 fn mint(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {154 let caller = T::CrossAccountId::from_eth(caller);155 let to = T::CrossAccountId::from_eth(to);156 let amount = amount.try_into().map_err(|_| "amount overflow")?;157 let budget = self158 .recorder159 .weight_calls_budget(<StructureWeight<T>>::find_parent());160 <Pallet<T>>::create_item(&self, &caller, (to, amount), &budget)161 .map_err(dispatch_to_evm::<T>)?;162 Ok(true)163 }164}165166#[solidity_interface(name = ERC20UniqueExtensions)]167impl<T: Config> FungibleHandle<T>168where169 T::AccountId: From<[u8; 32]>,170{171 /// @dev Function to check the amount of tokens that an owner allowed to a spender.172 /// @param owner crossAddress The address which owns the funds.173 /// @param spender crossAddress The address which will spend the funds.174 /// @return A uint256 specifying the amount of tokens still available for the spender.175 fn allowance_cross(176 &self,177 owner: pallet_common::eth::CrossAddress,178 spender: pallet_common::eth::CrossAddress,179 ) -> Result<U256> {180 let owner = owner.into_sub_cross_account::<T>()?;181 let spender = spender.into_sub_cross_account::<T>()?;182183 Ok(<Allowance<T>>::get((self.id, owner, spender)).into())184 }185186 /// @notice A description for the collection.187 fn description(&self) -> Result<String> {188 Ok(decode_utf16(self.description.iter().copied())189 .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))190 .collect::<String>())191 }192193 #[weight(<SelfWeightOf<T>>::create_item())]194 fn mint_cross(195 &mut self,196 caller: Caller,197 to: pallet_common::eth::CrossAddress,198 amount: U256,199 ) -> Result<bool> {200 let caller = T::CrossAccountId::from_eth(caller);201 let to = to.into_sub_cross_account::<T>()?;202 let amount = amount.try_into().map_err(|_| "amount overflow")?;203 let budget = self204 .recorder205 .weight_calls_budget(<StructureWeight<T>>::find_parent());206 <Pallet<T>>::create_item(&self, &caller, (to, amount), &budget)207 .map_err(dispatch_to_evm::<T>)?;208 Ok(true)209 }210211 #[weight(<SelfWeightOf<T>>::approve())]212 fn approve_cross(213 &mut self,214 caller: Caller,215 spender: pallet_common::eth::CrossAddress,216 amount: U256,217 ) -> Result<bool> {218 let caller = T::CrossAccountId::from_eth(caller);219 let spender = spender.into_sub_cross_account::<T>()?;220 let amount = amount.try_into().map_err(|_| "amount overflow")?;221222 <Pallet<T>>::set_allowance(self, &caller, &spender, amount)223 .map_err(dispatch_to_evm::<T>)?;224 Ok(true)225 }226227 /// Burn tokens from account228 /// @dev Function that burns an `amount` of the tokens of a given account,229 /// deducting from the sender's allowance for said account.230 /// @param from The account whose tokens will be burnt.231 /// @param amount The amount that will be burnt.232 #[solidity(hide)]233 #[weight(<SelfWeightOf<T>>::burn_from())]234 fn burn_from(&mut self, caller: Caller, from: Address, amount: U256) -> Result<bool> {235 let caller = T::CrossAccountId::from_eth(caller);236 let from = T::CrossAccountId::from_eth(from);237 let amount = amount.try_into().map_err(|_| "amount overflow")?;238 let budget = self239 .recorder240 .weight_calls_budget(<StructureWeight<T>>::find_parent());241242 <Pallet<T>>::burn_from(self, &caller, &from, amount, &budget)243 .map_err(dispatch_to_evm::<T>)?;244 Ok(true)245 }246247 /// Burn tokens from account248 /// @dev Function that burns an `amount` of the tokens of a given account,249 /// deducting from the sender's allowance for said account.250 /// @param from The account whose tokens will be burnt.251 /// @param amount The amount that will be burnt.252 #[weight(<SelfWeightOf<T>>::burn_from())]253 fn burn_from_cross(254 &mut self,255 caller: Caller,256 from: pallet_common::eth::CrossAddress,257 amount: U256,258 ) -> Result<bool> {259 let caller = T::CrossAccountId::from_eth(caller);260 let from = from.into_sub_cross_account::<T>()?;261 let amount = amount.try_into().map_err(|_| "amount overflow")?;262 let budget = self263 .recorder264 .weight_calls_budget(<StructureWeight<T>>::find_parent());265266 <Pallet<T>>::burn_from(self, &caller, &from, amount, &budget)267 .map_err(dispatch_to_evm::<T>)?;268 Ok(true)269 }270271 /// Mint tokens for multiple accounts.272 /// @param amounts array of pairs of account address and amount273 #[weight(<SelfWeightOf<T>>::create_multiple_items_ex(amounts.len() as u32))]274 fn mint_bulk(&mut self, caller: Caller, amounts: Vec<AmountForAddress>) -> Result<bool> {275 let caller = T::CrossAccountId::from_eth(caller);276 let budget = self277 .recorder278 .weight_calls_budget(<StructureWeight<T>>::find_parent());279 let amounts = amounts280 .into_iter()281 .map(|AmountForAddress { to, amount }| {282 Ok((283 T::CrossAccountId::from_eth(to),284 amount.try_into().map_err(|_| "amount overflow")?,285 ))286 })287 .collect::<Result<_>>()?;288289 <Pallet<T>>::create_multiple_items(&self, &caller, amounts, &budget)290 .map_err(dispatch_to_evm::<T>)?;291 Ok(true)292 }293294 #[weight(<SelfWeightOf<T>>::transfer())]295 fn transfer_cross(296 &mut self,297 caller: Caller,298 to: pallet_common::eth::CrossAddress,299 amount: U256,300 ) -> Result<bool> {301 let caller = T::CrossAccountId::from_eth(caller);302 let to = to.into_sub_cross_account::<T>()?;303 let amount = amount.try_into().map_err(|_| "amount overflow")?;304 let budget = self305 .recorder306 .weight_calls_budget(<StructureWeight<T>>::find_parent());307308 <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;309 Ok(true)310 }311312 #[weight(<SelfWeightOf<T>>::transfer_from())]313 fn transfer_from_cross(314 &mut self,315 caller: Caller,316 from: pallet_common::eth::CrossAddress,317 to: pallet_common::eth::CrossAddress,318 amount: U256,319 ) -> Result<bool> {320 let caller = T::CrossAccountId::from_eth(caller);321 let from = from.into_sub_cross_account::<T>()?;322 let to = to.into_sub_cross_account::<T>()?;323 let amount = amount.try_into().map_err(|_| "amount overflow")?;324 let budget = self325 .recorder326 .weight_calls_budget(<StructureWeight<T>>::find_parent());327328 <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)329 .map_err(dispatch_to_evm::<T>)?;330 Ok(true)331 }332333 /// @notice Returns collection helper contract address334 fn collection_helper_address(&self) -> Result<Address> {335 Ok(T::ContractAddress::get())336 }337}338339#[solidity_interface(340 name = UniqueFungible,341 is(342 ERC20,343 ERC20Mintable,344 ERC20UniqueExtensions,345 Collection(via(common_mut returns CollectionHandle<T>)),346 )347)]348impl<T: Config> FungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}349350generate_stubgen!(gen_impl, UniqueFungibleCall<()>, true);351generate_stubgen!(gen_iface, UniqueFungibleCall<()>, false);352353impl<T: Config> CommonEvmHandler for FungibleHandle<T>354where355 T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,356{357 const CODE: &'static [u8] = include_bytes!("./stubs/UniqueFungible.raw");358359 fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {360 call::<T, UniqueFungibleCall<T>, _, _>(handle, self)361 }362}pallets/fungible/src/lib.rsdiffbeforeafterboth--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -165,8 +165,8 @@
pub type Allowance<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
- Key<Blake2_128, T::CrossAccountId>,
- Key<Blake2_128Concat, T::CrossAccountId>,
+ Key<Blake2_128, T::CrossAccountId>, // Owner
+ Key<Blake2_128Concat, T::CrossAccountId>, // Spender
),
Value = u128,
QueryKind = ValueQuery,
pallets/refungible/src/erc_token.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -31,7 +31,7 @@
use pallet_common::{
CommonWeightInfo,
erc::{CommonEvmHandler, PrecompileResult},
- eth::collection_id_to_address,
+ eth::{collection_id_to_address, CrossAddress},
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};
@@ -207,11 +207,7 @@
/// @param owner crossAddress The address which owns the funds.
/// @param spender crossAddress The address which will spend the funds.
/// @return A uint256 specifying the amount of tokens still available for the spender.
- fn allowance_cross(
- &self,
- owner: pallet_common::eth::CrossAddress,
- spender: pallet_common::eth::CrossAddress,
- ) -> Result<U256> {
+ fn allowance_cross(&self, owner: CrossAddress, spender: CrossAddress) -> Result<U256> {
let owner = owner.into_sub_cross_account::<T>()?;
let spender = spender.into_sub_cross_account::<T>()?;
@@ -245,7 +241,7 @@
fn burn_from_cross(
&mut self,
caller: Caller,
- from: pallet_common::eth::CrossAddress,
+ from: CrossAddress,
amount: U256,
) -> Result<bool> {
let caller = T::CrossAccountId::from_eth(caller);
@@ -271,7 +267,7 @@
fn approve_cross(
&mut self,
caller: Caller,
- spender: pallet_common::eth::CrossAddress,
+ spender: CrossAddress,
amount: U256,
) -> Result<bool> {
let caller = T::CrossAccountId::from_eth(caller);
@@ -298,12 +294,7 @@
/// @param to The crossaccount to transfer to.
/// @param amount The amount to be transferred.
#[weight(<CommonWeights<T>>::transfer())]
- fn transfer_cross(
- &mut self,
- caller: Caller,
- to: pallet_common::eth::CrossAddress,
- amount: U256,
- ) -> Result<bool> {
+ fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {
let caller = T::CrossAccountId::from_eth(caller);
let to = to.into_sub_cross_account::<T>()?;
let amount = amount.try_into().map_err(|_| "amount overflow")?;
@@ -324,8 +315,8 @@
fn transfer_from_cross(
&mut self,
caller: Caller,
- from: pallet_common::eth::CrossAddress,
- to: pallet_common::eth::CrossAddress,
+ from: CrossAddress,
+ to: CrossAddress,
amount: U256,
) -> Result<bool> {
let caller = T::CrossAccountId::from_eth(caller);
pallets/refungible/src/lib.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -240,13 +240,13 @@
QueryKind = ValueQuery,
>;
- /// Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.
+ /// Spender set by a wallet owner that could perform certain transactions on all tokens in the wallet.
#[pallet::storage]
pub type CollectionAllowance<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
Key<Blake2_128Concat, T::CrossAccountId>, // Owner
- Key<Blake2_128Concat, T::CrossAccountId>, // Operator
+ Key<Blake2_128Concat, T::CrossAccountId>, // Spender
),
Value = bool,
QueryKind = ValueQuery,
@@ -1403,18 +1403,18 @@
pub fn set_allowance_for_all(
collection: &RefungibleHandle<T>,
owner: &T::CrossAccountId,
- operator: &T::CrossAccountId,
+ spender: &T::CrossAccountId,
approve: bool,
) -> DispatchResult {
<PalletCommon<T>>::set_allowance_for_all(
collection,
owner,
- operator,
+ spender,
approve,
- || <CollectionAllowance<T>>::insert((collection.id, owner, operator), approve),
+ || <CollectionAllowance<T>>::insert((collection.id, owner, spender), approve),
ERC721Events::ApprovalForAll {
owner: *owner.as_eth(),
- operator: *operator.as_eth(),
+ operator: *spender.as_eth(),
approved: approve,
}
.to_log(collection_id_to_address(collection.id)),
@@ -1425,9 +1425,9 @@
pub fn allowance_for_all(
collection: &RefungibleHandle<T>,
owner: &T::CrossAccountId,
- operator: &T::CrossAccountId,
+ spender: &T::CrossAccountId,
) -> bool {
- <CollectionAllowance<T>>::get((collection.id, owner, operator))
+ <CollectionAllowance<T>>::get((collection.id, owner, spender))
}
pub fn repair_item(collection: &RefungibleHandle<T>, token: TokenId) -> DispatchResult {