git.delta.rocks / unique-network / refs/commits / 285030f49a3f

difftreelog

Merge branch 'feature/multi-assets-redone' of https://github.com/UniqueNetwork/unique-chain into feature/multi-assets-redone

Dev2022-09-14parents: #d8e349d #a106e3d.patch.diff
in: master

72 files changed

modified.maintain/scripts/generate_sol.shdiffbeforeafterboth
1#!/bin/sh1#!/bin/sh
2set -eu2set -eu
3
4PRETTIER_CONFIG="$(pwd)""/.prettierrc"
35
4tmp=$(mktemp)6tmp=$(mktemp)
5cargo test --package $PACKAGE -- $NAME --exact --nocapture --ignored | tee $tmp7cargo test --package $PACKAGE -- $NAME --exact --nocapture --ignored | tee $tmp
6raw=$(mktemp --suffix .sol)8raw=$(mktemp --suffix .sol)
7sed -n '/=== SNIP START ===/, /=== SNIP END ===/{ /=== SNIP START ===/! { /=== SNIP END ===/! p } }' $tmp > $raw9sed -n '/=== SNIP START ===/, /=== SNIP END ===/{ /=== SNIP START ===/! { /=== SNIP END ===/! p } }' $tmp > $raw
10
8formatted=$(mktemp)11formatted=$(mktemp)
9prettier --use-tabs $raw > $formatted12prettier --config $PRETTIER_CONFIG $raw > $formatted
1013
11mv $formatted $OUTPUT14mv $formatted $OUTPUT
1215
added.prettierignorediffbeforeafterboth

no changes

added.prettierrcdiffbeforeafterboth

no changes

modifiedCargo.lockdiffbeforeafterboth
2324[[package]]2324[[package]]
2325name = "fc-consensus"2325name = "fc-consensus"
2326version = "2.0.0-dev"2326version = "2.0.0-dev"
2327source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2327source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2328dependencies = [2328dependencies = [
2329 "async-trait",2329 "async-trait",
2330 "fc-db",2330 "fc-db",
2343[[package]]2343[[package]]
2344name = "fc-db"2344name = "fc-db"
2345version = "2.0.0-dev"2345version = "2.0.0-dev"
2346source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2346source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2347dependencies = [2347dependencies = [
2348 "fp-storage",2348 "fp-storage",
2349 "kvdb-rocksdb",2349 "kvdb-rocksdb",
2359[[package]]2359[[package]]
2360name = "fc-mapping-sync"2360name = "fc-mapping-sync"
2361version = "2.0.0-dev"2361version = "2.0.0-dev"
2362source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2362source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2363dependencies = [2363dependencies = [
2364 "fc-db",2364 "fc-db",
2365 "fp-consensus",2365 "fp-consensus",
2376[[package]]2376[[package]]
2377name = "fc-rpc"2377name = "fc-rpc"
2378version = "2.0.0-dev"2378version = "2.0.0-dev"
2379source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2379source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2380dependencies = [2380dependencies = [
2381 "ethereum",2381 "ethereum",
2382 "ethereum-types",2382 "ethereum-types",
2416[[package]]2416[[package]]
2417name = "fc-rpc-core"2417name = "fc-rpc-core"
2418version = "1.1.0-dev"2418version = "1.1.0-dev"
2419source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2419source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2420dependencies = [2420dependencies = [
2421 "ethereum",2421 "ethereum",
2422 "ethereum-types",2422 "ethereum-types",
2557[[package]]2557[[package]]
2558name = "fp-consensus"2558name = "fp-consensus"
2559version = "2.0.0-dev"2559version = "2.0.0-dev"
2560source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2560source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2561dependencies = [2561dependencies = [
2562 "ethereum",2562 "ethereum",
2563 "parity-scale-codec 3.1.5",2563 "parity-scale-codec 3.1.5",
2569[[package]]2569[[package]]
2570name = "fp-evm"2570name = "fp-evm"
2571version = "3.0.0-dev"2571version = "3.0.0-dev"
2572source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2572source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2573dependencies = [2573dependencies = [
2574 "evm",2574 "evm",
2575 "frame-support",2575 "frame-support",
2583[[package]]2583[[package]]
2584name = "fp-evm-mapping"2584name = "fp-evm-mapping"
2585version = "0.1.0"2585version = "0.1.0"
2586source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2586source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2587dependencies = [2587dependencies = [
2588 "frame-support",2588 "frame-support",
2589 "sp-core",2589 "sp-core",
2592[[package]]2592[[package]]
2593name = "fp-rpc"2593name = "fp-rpc"
2594version = "3.0.0-dev"2594version = "3.0.0-dev"
2595source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2595source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2596dependencies = [2596dependencies = [
2597 "ethereum",2597 "ethereum",
2598 "ethereum-types",2598 "ethereum-types",
2609[[package]]2609[[package]]
2610name = "fp-self-contained"2610name = "fp-self-contained"
2611version = "1.0.0-dev"2611version = "1.0.0-dev"
2612source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2612source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2613dependencies = [2613dependencies = [
2614 "ethereum",2614 "ethereum",
2615 "frame-support",2615 "frame-support",
2625[[package]]2625[[package]]
2626name = "fp-storage"2626name = "fp-storage"
2627version = "2.0.0"2627version = "2.0.0"
2628source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"2628source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
2629dependencies = [2629dependencies = [
2630 "parity-scale-codec 3.1.5",2630 "parity-scale-codec 3.1.5",
2631]2631]
5543[[package]]5543[[package]]
5544name = "pallet-base-fee"5544name = "pallet-base-fee"
5545version = "1.0.0"5545version = "1.0.0"
5546source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"5546source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
5547dependencies = [5547dependencies = [
5548 "fp-evm",5548 "fp-evm",
5549 "frame-support",5549 "frame-support",
5758[[package]]5758[[package]]
5759name = "pallet-ethereum"5759name = "pallet-ethereum"
5760version = "4.0.0-dev"5760version = "4.0.0-dev"
5761source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"5761source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
5762dependencies = [5762dependencies = [
5763 "ethereum",5763 "ethereum",
5764 "ethereum-types",5764 "ethereum-types",
5787[[package]]5787[[package]]
5788name = "pallet-evm"5788name = "pallet-evm"
5789version = "6.0.0-dev"5789version = "6.0.0-dev"
5790source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27#69945f20e8dc06ab9e0dd636848a8db6a408c71c"5790source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.27-fee-limit#0ae36821312f4a26e7f96225f1b2cb16216cddf5"
5791dependencies = [5791dependencies = [
5792 "evm",5792 "evm",
5793 "fp-evm",5793 "fp-evm",
5842 "pallet-common",5842 "pallet-common",
5843 "pallet-evm",5843 "pallet-evm",
5844 "pallet-evm-coder-substrate",5844 "pallet-evm-coder-substrate",
5845 "pallet-evm-transaction-payment",
5845 "parity-scale-codec 3.1.5",5846 "parity-scale-codec 3.1.5",
5846 "scale-info",5847 "scale-info",
5847 "sp-core",5848 "sp-core",
modifiedclient/rpc/Cargo.tomldiffbeforeafterboth
19sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }19sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
20sp-rpc = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }20sp-rpc = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
21sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }21sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2323
modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
577 BlockNumber: Decode + Member + AtLeast32BitUnsigned,577 BlockNumber: Decode + Member + AtLeast32BitUnsigned,
578 AccountId: Decode,578 AccountId: Decode,
579 C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,579 C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
580 C::Api: AppPromotionRuntimeApi<Block, BlockNumber, CrossAccountId, AccountId>,
581 CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,580 CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,
581 C::Api: AppPromotionRuntimeApi<Block, BlockNumber, CrossAccountId, AccountId>,
582{582{
583 pass_method!(total_staked(staker: Option<CrossAccountId>) -> String => |v| v.to_string(), app_promotion_api);583 pass_method!(total_staked(staker: Option<CrossAccountId>) -> String => |v| v.to_string(), app_promotion_api);
584 pass_method!(total_staked_per_block(staker: CrossAccountId) -> Vec<(BlockNumber, String)> =>584 pass_method!(total_staked_per_block(staker: CrossAccountId) -> Vec<(BlockNumber, String)> =>
addeddoc/sponsoring-flow.drawio.svgdiffbeforeafterboth

no changes

addeddoc/sponsoring.mddiffbeforeafterboth

no changes

modifiednode/cli/Cargo.tomldiffbeforeafterboth
309jsonrpsee = { version = "0.14.0", features = ["server", "macros"] }309jsonrpsee = { version = "0.14.0", features = ["server", "macros"] }
310tokio = { version = "1.19.2", features = ["time"] }310tokio = { version = "1.19.2", features = ["time"] }
311311
312fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }312fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
313fc-consensus = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }313fc-consensus = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
314fc-mapping-sync = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }314fc-mapping-sync = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
315fc-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }315fc-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
316fc-db = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }316fc-db = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
317fp-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }317fp-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
318pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }318pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
319319
320unique-rpc = { default-features = false, path = "../rpc" }320unique-rpc = { default-features = false, path = "../rpc" }
321app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}321app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}
modifiednode/rpc/Cargo.tomldiffbeforeafterboth
40substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }40substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
41tokio = { version = "1.19.2", features = ["macros", "sync"] }41tokio = { version = "1.19.2", features = ["macros", "sync"] }
4242
43pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }43pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
44fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }44fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
45fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }45fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
46fp-storage = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }46fp-storage = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
47fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }47fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
48fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }48fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
49fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }49fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
5050
51pallet-common = { default-features = false, path = "../../pallets/common" }51pallet-common = { default-features = false, path = "../../pallets/common" }
52up-common = { path = "../../primitives/common" }52up-common = { path = "../../primitives/common" }
modifiedpallets/app-promotion/Cargo.tomldiffbeforeafterboth
52pallet-balances ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }52pallet-balances ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
53pallet-timestamp ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }53pallet-timestamp ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
54pallet-randomness-collective-flip ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }54pallet-randomness-collective-flip ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
55pallet-evm ={ default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }55pallet-evm ={ default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
56sp-std ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }56sp-std ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
57sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }57sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
58sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }58sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
modifiedpallets/common/Cargo.tomldiffbeforeafterboth
17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
19frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }19frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
20fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }20fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
22pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }22pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
23evm-coder = { default-features = false, path = '../../crates/evm-coder' }23evm-coder = { default-features = false, path = '../../crates/evm-coder' }
24ethereum = { version = "0.12.0", default-features = false }24ethereum = { version = "0.12.0", default-features = false }
25pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }25pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2626
27serde = { version = "1.0.130", default-features = false }27serde = { version = "1.0.130", default-features = false }
28scale-info = { version = "2.0.1", default-features = false, features = [28scale-info = { version = "2.0.1", default-features = false, features = [
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
20 solidity_interface, solidity, ToLog,20 solidity_interface, solidity, ToLog,
21 types::*,21 types::*,
22 execution::{Result, Error},22 execution::{Result, Error},
23 weight,
23};24};
24pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};25pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};
25use pallet_evm_coder_substrate::dispatch_to_evm;26use pallet_evm_coder_substrate::dispatch_to_evm;
31use alloc::format;32use alloc::format;
3233
33use crate::{34use crate::{
34 Pallet, CollectionHandle, Config, CollectionProperties,35 Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,
35 eth::{convert_cross_account_to_uint256, convert_uint256_to_cross_account},36 eth::{
37 convert_cross_account_to_uint256, convert_uint256_to_cross_account,
38 convert_cross_account_to_tuple,
39 },
40 weights::WeightInfo,
36};41};
3742
38/// Events for ethereum collection helper.43/// Events for ethereum collection helper.
69 ///74 ///
70 /// @param key Property key.75 /// @param key Property key.
71 /// @param value Propery value.76 /// @param value Propery value.
77 #[weight(<SelfWeightOf<T>>::set_collection_properties(1))]
72 fn set_collection_property(78 fn set_collection_property(
73 &mut self,79 &mut self,
74 caller: caller,80 caller: caller,
88 /// Delete collection property.94 /// Delete collection property.
89 ///95 ///
90 /// @param key Property key.96 /// @param key Property key.
97 #[weight(<SelfWeightOf<T>>::delete_collection_properties(1))]
91 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {98 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {
99 self.consume_store_reads_and_writes(1, 1)?;
100
92 let caller = T::CrossAccountId::from_eth(caller);101 let caller = T::CrossAccountId::from_eth(caller);
93 let key = <Vec<u8>>::from(key)102 let key = <Vec<u8>>::from(key)
94 .try_into()103 .try_into()
120 ///129 ///
121 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.130 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
122 fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {131 fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {
132 self.consume_store_reads_and_writes(1, 1)?;
133
123 check_is_owner_or_admin(caller, self)?;134 check_is_owner_or_admin(caller, self)?;
124135
125 let sponsor = T::CrossAccountId::from_eth(sponsor);136 let sponsor = T::CrossAccountId::from_eth(sponsor);
138 caller: caller,149 caller: caller,
139 sponsor: uint256,150 sponsor: uint256,
140 ) -> Result<void> {151 ) -> Result<void> {
152 self.consume_store_reads_and_writes(1, 1)?;
153
141 check_is_owner_or_admin(caller, self)?;154 check_is_owner_or_admin(caller, self)?;
142155
143 let sponsor = convert_uint256_to_cross_account::<T>(sponsor);156 let sponsor = convert_uint256_to_cross_account::<T>(sponsor);
146 save(self)159 save(self)
147 }160 }
148161
149 // /// Whether there is a pending sponsor.162 /// Whether there is a pending sponsor.
150 fn has_collection_pending_sponsor(&self) -> Result<bool> {163 fn has_collection_pending_sponsor(&self) -> Result<bool> {
151 Ok(matches!(164 Ok(matches!(
152 self.collection.sponsorship,165 self.collection.sponsorship,
158 ///171 ///
159 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.172 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.
160 fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result<void> {173 fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result<void> {
174 self.consume_store_writes(1)?;
175
161 let caller = T::CrossAccountId::from_eth(caller);176 let caller = T::CrossAccountId::from_eth(caller);
162 if !self177 if !self
163 .confirm_sponsorship(caller.as_sub())178 .confirm_sponsorship(caller.as_sub())
170185
171 /// Remove collection sponsor.186 /// Remove collection sponsor.
172 fn remove_collection_sponsor(&mut self, caller: caller) -> Result<void> {187 fn remove_collection_sponsor(&mut self, caller: caller) -> Result<void> {
188 self.consume_store_reads_and_writes(1, 1)?;
173 check_is_owner_or_admin(caller, self)?;189 check_is_owner_or_admin(caller, self)?;
174 self.remove_sponsor().map_err(dispatch_to_evm::<T>)?;190 self.remove_sponsor().map_err(dispatch_to_evm::<T>)?;
175 save(self)191 save(self)
206 /// @param value Value of the limit.222 /// @param value Value of the limit.
207 #[solidity(rename_selector = "setCollectionLimit")]223 #[solidity(rename_selector = "setCollectionLimit")]
208 fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result<void> {224 fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result<void> {
225 self.consume_store_reads_and_writes(1, 1)?;
226
209 check_is_owner_or_admin(caller, self)?;227 check_is_owner_or_admin(caller, self)?;
210 let mut limits = self.limits.clone();228 let mut limits = self.limits.clone();
211229
249 /// @param value Value of the limit.267 /// @param value Value of the limit.
250 #[solidity(rename_selector = "setCollectionLimit")]268 #[solidity(rename_selector = "setCollectionLimit")]
251 fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result<void> {269 fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result<void> {
270 self.consume_store_reads_and_writes(1, 1)?;
271
252 check_is_owner_or_admin(caller, self)?;272 check_is_owner_or_admin(caller, self)?;
253 let mut limits = self.limits.clone();273 let mut limits = self.limits.clone();
254274
275 }295 }
276296
277 /// Get contract address.297 /// Get contract address.
278 fn contract_address(&self, _caller: caller) -> Result<address> {298 fn contract_address(&self) -> Result<address> {
279 Ok(crate::eth::collection_id_to_address(self.id))299 Ok(crate::eth::collection_id_to_address(self.id))
280 }300 }
281301
286 caller: caller,306 caller: caller,
287 new_admin: uint256,307 new_admin: uint256,
288 ) -> Result<void> {308 ) -> Result<void> {
309 self.consume_store_writes(2)?;
310
289 let caller = T::CrossAccountId::from_eth(caller);311 let caller = T::CrossAccountId::from_eth(caller);
290 let new_admin = convert_uint256_to_cross_account::<T>(new_admin);312 let new_admin = convert_uint256_to_cross_account::<T>(new_admin);
291 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;313 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;
299 caller: caller,321 caller: caller,
300 admin: uint256,322 admin: uint256,
301 ) -> Result<void> {323 ) -> Result<void> {
324 self.consume_store_writes(2)?;
325
302 let caller = T::CrossAccountId::from_eth(caller);326 let caller = T::CrossAccountId::from_eth(caller);
303 let admin = convert_uint256_to_cross_account::<T>(admin);327 let admin = convert_uint256_to_cross_account::<T>(admin);
304 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;328 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
308 /// Add collection admin.332 /// Add collection admin.
309 /// @param newAdmin Address of the added administrator.333 /// @param newAdmin Address of the added administrator.
310 fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result<void> {334 fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result<void> {
335 self.consume_store_writes(2)?;
336
311 let caller = T::CrossAccountId::from_eth(caller);337 let caller = T::CrossAccountId::from_eth(caller);
312 let new_admin = T::CrossAccountId::from_eth(new_admin);338 let new_admin = T::CrossAccountId::from_eth(new_admin);
313 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;339 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;
318 ///344 ///
319 /// @param admin Address of the removed administrator.345 /// @param admin Address of the removed administrator.
320 fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result<void> {346 fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result<void> {
347 self.consume_store_writes(2)?;
348
321 let caller = T::CrossAccountId::from_eth(caller);349 let caller = T::CrossAccountId::from_eth(caller);
322 let admin = T::CrossAccountId::from_eth(admin);350 let admin = T::CrossAccountId::from_eth(admin);
323 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;351 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
329 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'357 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
330 #[solidity(rename_selector = "setCollectionNesting")]358 #[solidity(rename_selector = "setCollectionNesting")]
331 fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result<void> {359 fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result<void> {
360 self.consume_store_reads_and_writes(1, 1)?;
361
332 check_is_owner_or_admin(caller, self)?;362 check_is_owner_or_admin(caller, self)?;
333363
334 let mut permissions = self.collection.permissions.clone();364 let mut permissions = self.collection.permissions.clone();
358 enable: bool,388 enable: bool,
359 collections: Vec<address>,389 collections: Vec<address>,
360 ) -> Result<void> {390 ) -> Result<void> {
391 self.consume_store_reads_and_writes(1, 1)?;
392
361 if collections.is_empty() {393 if collections.is_empty() {
362 return Err("no addresses provided".into());394 return Err("no addresses provided".into());
363 }395 }
401 /// 0 for Normal433 /// 0 for Normal
402 /// 1 for AllowList434 /// 1 for AllowList
403 fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result<void> {435 fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result<void> {
436 self.consume_store_reads_and_writes(1, 1)?;
437
404 check_is_owner_or_admin(caller, self)?;438 check_is_owner_or_admin(caller, self)?;
405 let permissions = CollectionPermissions {439 let permissions = CollectionPermissions {
406 access: Some(match mode {440 access: Some(match mode {
420 save(self)454 save(self)
421 }455 }
422456
457 /// Checks that user allowed to operate with collection.
458 ///
459 /// @param user User address to check.
460 fn allowed(&self, user: address) -> Result<bool> {
461 Ok(Pallet::<T>::allowed(
462 self.id,
463 T::CrossAccountId::from_eth(user),
464 ))
465 }
466
423 /// Add the user to the allowed list.467 /// Add the user to the allowed list.
424 ///468 ///
425 /// @param user Address of a trusted user.469 /// @param user Address of a trusted user.
426 fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {470 fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {
471 self.consume_store_writes(1)?;
472
427 let caller = T::CrossAccountId::from_eth(caller);473 let caller = T::CrossAccountId::from_eth(caller);
428 let user = T::CrossAccountId::from_eth(user);474 let user = T::CrossAccountId::from_eth(user);
429 <Pallet<T>>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;475 <Pallet<T>>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;
430 Ok(())476 Ok(())
431 }477 }
432478
479 /// Add substrate user to allowed list.
480 ///
481 /// @param user User substrate address.
482 fn add_to_collection_allow_list_substrate(
483 &mut self,
484 caller: caller,
485 user: uint256,
486 ) -> Result<void> {
487 self.consume_store_writes(1)?;
488
489 let caller = T::CrossAccountId::from_eth(caller);
490 let user = convert_uint256_to_cross_account::<T>(user);
491 Pallet::<T>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;
492 Ok(())
493 }
494
433 /// Remove the user from the allowed list.495 /// Remove the user from the allowed list.
434 ///496 ///
435 /// @param user Address of a removed user.497 /// @param user Address of a removed user.
436 fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {498 fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {
499 self.consume_store_writes(1)?;
500
437 let caller = T::CrossAccountId::from_eth(caller);501 let caller = T::CrossAccountId::from_eth(caller);
438 let user = T::CrossAccountId::from_eth(user);502 let user = T::CrossAccountId::from_eth(user);
439 <Pallet<T>>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;503 <Pallet<T>>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;
440 Ok(())504 Ok(())
441 }505 }
442506
507 /// Remove substrate user from allowed list.
508 ///
509 /// @param user User substrate address.
510 fn remove_from_collection_allow_list_substrate(
511 &mut self,
512 caller: caller,
513 user: uint256,
514 ) -> Result<void> {
515 self.consume_store_writes(1)?;
516
517 let caller = T::CrossAccountId::from_eth(caller);
518 let user = convert_uint256_to_cross_account::<T>(user);
519 Pallet::<T>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;
520 Ok(())
521 }
522
443 /// Switch permission for minting.523 /// Switch permission for minting.
444 ///524 ///
445 /// @param mode Enable if "true".525 /// @param mode Enable if "true".
446 fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result<void> {526 fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result<void> {
527 self.consume_store_reads_and_writes(1, 1)?;
528
447 check_is_owner_or_admin(caller, self)?;529 check_is_owner_or_admin(caller, self)?;
448 let permissions = CollectionPermissions {530 let permissions = CollectionPermissions {
449 mint_mode: Some(mode),531 mint_mode: Some(mode),
481 /// Returns collection type563 /// Returns collection type
482 ///564 ///
483 /// @return `Fungible` or `NFT` or `ReFungible`565 /// @return `Fungible` or `NFT` or `ReFungible`
484 fn unique_collection_type(&mut self) -> Result<string> {566 fn unique_collection_type(&self) -> Result<string> {
485 let mode = match self.collection.mode {567 let mode = match self.collection.mode {
486 CollectionMode::Fungible(_) => "Fungible",568 CollectionMode::Fungible(_) => "Fungible",
487 CollectionMode::NFT => "NFT",569 CollectionMode::NFT => "NFT",
490 Ok(mode.into())572 Ok(mode.into())
491 }573 }
492574
575 /// Get collection owner.
576 ///
577 /// @return Tuble with sponsor address and his substrate mirror.
578 /// If address is canonical then substrate mirror is zero and vice versa.
579 fn collection_owner(&self) -> Result<(address, uint256)> {
580 Ok(convert_cross_account_to_tuple::<T>(
581 &T::CrossAccountId::from_sub(self.owner.clone()),
582 ))
583 }
584
493 /// Changes collection owner to another account585 /// Changes collection owner to another account
494 ///586 ///
495 /// @dev Owner can be changed only by current owner587 /// @dev Owner can be changed only by current owner
496 /// @param newOwner new owner account588 /// @param newOwner new owner account
497 fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {589 fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {
590 self.consume_store_writes(1)?;
591
498 let caller = T::CrossAccountId::from_eth(caller);592 let caller = T::CrossAccountId::from_eth(caller);
499 let new_owner = T::CrossAccountId::from_eth(new_owner);593 let new_owner = T::CrossAccountId::from_eth(new_owner);
500 self.set_owner_internal(caller, new_owner)594 self.set_owner_internal(caller, new_owner)
506 /// @dev Owner can be changed only by current owner600 /// @dev Owner can be changed only by current owner
507 /// @param newOwner new owner substrate account601 /// @param newOwner new owner substrate account
508 fn set_owner_substrate(&mut self, caller: caller, new_owner: uint256) -> Result<void> {602 fn set_owner_substrate(&mut self, caller: caller, new_owner: uint256) -> Result<void> {
603 self.consume_store_writes(1)?;
604
509 let caller = T::CrossAccountId::from_eth(caller);605 let caller = T::CrossAccountId::from_eth(caller);
510 let new_owner = convert_uint256_to_cross_account::<T>(new_owner);606 let new_owner = convert_uint256_to_cross_account::<T>(new_owner);
511 self.set_owner_internal(caller, new_owner)607 self.set_owner_internal(caller, new_owner)
512 .map_err(dispatch_to_evm::<T>)608 .map_err(dispatch_to_evm::<T>)
513 }609 }
610
611 // TODO: need implement AbiWriter for &Vec<T>
612 // fn collection_admins(&self) -> Result<Vec<(address, uint256)>> {
613 // let result = pallet_common::IsAdmin::<T>::iter_prefix((self.id,))
614 // .map(|(admin, _)| pallet_common::eth::convert_cross_account_to_tuple::<T>(&admin))
615 // .collect();
616 // Ok(result)
617 // }
514}618}
515619
620/// ### Note
621/// Do not forget to add: `self.consume_store_reads(1)?;`
516fn check_is_owner_or_admin<T: Config>(622fn check_is_owner_or_admin<T: Config>(
517 caller: caller,623 caller: caller,
518 collection: &CollectionHandle<T>,624 collection: &CollectionHandle<T>,
524 Ok(caller)630 Ok(caller)
525}631}
526632
633/// ### Note
634/// Do not forget to add: `self.consume_store_writes(1)?;`
527fn save<T: Config>(collection: &CollectionHandle<T>) -> Result<void> {635fn save<T: Config>(collection: &CollectionHandle<T>) -> Result<void> {
528 // TODO possibly delete for the lack of transaction
529 collection.consume_store_writes(1)?;
530 collection636 collection
531 .check_is_internal()637 .check_is_internal()
532 .map_err(dispatch_to_evm::<T>)?;638 .map_err(dispatch_to_evm::<T>)?;
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
1616
17//! The module contains a number of functions for converting and checking ethereum identifiers.17//! The module contains a number of functions for converting and checking ethereum identifiers.
1818
19use evm_coder::types::uint256;19use evm_coder::types::{uint256, address};
20pub use pallet_evm::account::{Config, CrossAccountId};20pub use pallet_evm::account::{Config, CrossAccountId};
21use sp_core::H160;21use sp_core::H160;
22use up_data_structs::CollectionId;22use up_data_structs::CollectionId;
70 T::CrossAccountId::from_sub(account_id)70 T::CrossAccountId::from_sub(account_id)
71}71}
72
73/// Convert `CrossAccountId` to `(address, uint256)`.
74pub fn convert_cross_account_to_tuple<T: Config>(
75 cross_account_id: &T::CrossAccountId,
76) -> (address, uint256)
77where
78 T::AccountId: AsRef<[u8; 32]>,
79{
80 if cross_account_id.is_canonical_substrate() {
81 let sub = convert_cross_account_to_uint256::<T>(cross_account_id);
82 (Default::default(), sub)
83 } else {
84 let eth = *cross_account_id.as_eth();
85 (eth, Default::default())
86 }
87}
7288
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
112 RmrkBoundedTheme,112 RmrkBoundedTheme,
113 RmrkNftChild,113 RmrkNftChild,
114 CollectionPermissions,114 CollectionPermissions,
115 SchemaVersion,
116};115};
117116
118pub use pallet::*;117pub use pallet::*;
202 ))201 ))
203 }202 }
203
204 /// Consume gas for reading and writing.
205 pub fn consume_store_reads_and_writes(
206 &self,
207 reads: u64,
208 writes: u64,
209 ) -> evm_coder::execution::Result<()> {
210 let weight = <T as frame_system::Config>::DbWeight::get();
211 let reads = weight.read.saturating_mul(reads);
212 let writes = weight.read.saturating_mul(writes);
213 self.recorder
214 .consume_gas(T::GasWeightMapping::weight_to_gas(
215 reads.saturating_add(writes),
216 ))
217 }
204218
205 /// Save collection to storage.219 /// Save collection to storage.
206 pub fn save(&self) -> DispatchResult {220 pub fn save(&self) -> DispatchResult {
310 }324 }
311325
312 /// Changes collection owner to another account326 /// Changes collection owner to another account
327 /// #### Store read/writes
328 /// 1 writes
313 fn set_owner_internal(329 fn set_owner_internal(
314 &mut self,330 &mut self,
315 caller: T::CrossAccountId,331 caller: T::CrossAccountId,
1292 }1308 }
12931309
1294 /// Toggle `user` participation in the `collection`'s allow list.1310 /// Toggle `user` participation in the `collection`'s allow list.
1311 /// #### Store read/writes
1312 /// 1 writes
1295 pub fn toggle_allowlist(1313 pub fn toggle_allowlist(
1296 collection: &CollectionHandle<T>,1314 collection: &CollectionHandle<T>,
1297 sender: &T::CrossAccountId,1315 sender: &T::CrossAccountId,
1312 }1330 }
13131331
1314 /// Toggle `user` participation in the `collection`'s admin list.1332 /// Toggle `user` participation in the `collection`'s admin list.
1333 /// #### Store read/writes
1334 /// 2 writes
1315 pub fn toggle_admin(1335 pub fn toggle_admin(
1316 collection: &CollectionHandle<T>,1336 collection: &CollectionHandle<T>,
1317 sender: &T::CrossAccountId,1337 sender: &T::CrossAccountId,
modifiedpallets/configuration/Cargo.tomldiffbeforeafterboth
16sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18sp-arithmetic = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }18sp-arithmetic = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
19fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
20smallvec = "1.6.1"20smallvec = "1.6.1"
2121
22[features]22[features]
modifiedpallets/evm-coder-substrate/Cargo.tomldiffbeforeafterboth
12sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }12sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
13ethereum = { version = "0.12.0", default-features = false }13ethereum = { version = "0.12.0", default-features = false }
14evm-coder = { default-features = false, path = "../../crates/evm-coder" }14evm-coder = { default-features = false, path = "../../crates/evm-coder" }
15pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }15pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
16pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }16pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
17frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }18frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
19frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }19frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
modifiedpallets/evm-contract-helpers/Cargo.tomldiffbeforeafterboth
19sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }19sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
2020
21# Unique21# Unique
22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
23fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }23fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
24up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }24up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }
2525
26# Locals26# Locals
27evm-coder = { default-features = false, path = '../../crates/evm-coder' }27evm-coder = { default-features = false, path = '../../crates/evm-coder' }
28pallet-common = { default-features = false, path = '../../pallets/common' }28pallet-common = { default-features = false, path = '../../pallets/common' }
29pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }29pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
30pallet-evm-transaction-payment = { default-features = false, path = '../../pallets/evm-transaction-payment' }
30up-data-structs = { default-features = false, path = '../../primitives/data-structs', features = [31up-data-structs = { default-features = false, path = '../../primitives/data-structs', features = [
31 'serde1',32 'serde1',
32] }33] }
modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
20use evm_coder::{20use evm_coder::{
21 abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*, ToLog,21 abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*, ToLog,
22};22};
23use pallet_evm::{
24 ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle,
25 account::CrossAccountId,
26};
23use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder, dispatch_to_evm};27use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder, dispatch_to_evm};
24use pallet_evm::{28use pallet_evm_transaction_payment::CallContext;
25 ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle,
26 account::CrossAccountId,
27};
28use sp_core::H160;29use sp_core::{H160, U256};
29use up_data_structs::SponsorshipState;30use up_data_structs::SponsorshipState;
30use crate::{31use crate::{
31 AllowlistEnabled, Config, Owner, Pallet, SponsorBasket, SponsoringRateLimit, SponsoringModeT,32 AllowlistEnabled, Config, Owner, Pallet, SponsorBasket, SponsoringFeeLimit,
32 Sponsoring,33 SponsoringRateLimit, SponsoringModeT, Sponsoring,
33};34};
34use frame_support::traits::Get;35use frame_support::traits::Get;
171 fn get_sponsor(&self, contract_address: address) -> Result<(address, uint256)> {172 fn get_sponsor(&self, contract_address: address) -> Result<(address, uint256)> {
172 let sponsor =173 let sponsor =
173 Pallet::<T>::get_sponsor(contract_address).ok_or("Contract has no sponsor")?;174 Pallet::<T>::get_sponsor(contract_address).ok_or("Contract has no sponsor")?;
174 let result: (address, uint256) = if sponsor.is_canonical_substrate() {
175 let sponsor = pallet_common::eth::convert_cross_account_to_uint256::<T>(&sponsor);175 Ok(pallet_common::eth::convert_cross_account_to_tuple::<T>(
176 (Default::default(), sponsor)176 &sponsor,
177 } else {177 ))
178 let sponsor = *sponsor.as_eth();
179 (sponsor, Default::default())
180 };
181 Ok(result)
182 }178 }
183179
184 /// Check tat contract has confirmed sponsor.180 /// Check tat contract has confirmed sponsor.
222 }218 }
223219
224 /// Get current contract sponsoring rate limit220 /// Get current contract sponsoring rate limit
225 /// @param contractAddress Contract to get sponsoring mode of221 /// @param contractAddress Contract to get sponsoring rate limit of
226 /// @return uint32 Amount of blocks between two sponsored transactions222 /// @return uint32 Amount of blocks between two sponsored transactions
227 fn get_sponsoring_rate_limit(&self, contract_address: address) -> Result<uint32> {223 fn get_sponsoring_rate_limit(&self, contract_address: address) -> Result<uint32> {
224 self.recorder().consume_sload()?;
225
228 Ok(<SponsoringRateLimit<T>>::get(contract_address)226 Ok(<SponsoringRateLimit<T>>::get(contract_address)
229 .try_into()227 .try_into()
250 Ok(())248 Ok(())
251 }249 }
250
251 /// Set contract sponsoring fee limit
252 /// @dev Sponsoring fee limit - is maximum fee that could be spent by
253 /// single transaction
254 /// @param contractAddress Contract to change sponsoring fee limit of
255 /// @param feeLimit Fee limit
256 /// @dev Only contract owner can change this setting
257 fn set_sponsoring_fee_limit(
258 &mut self,
259 caller: caller,
260 contract_address: address,
261 fee_limit: uint256,
262 ) -> Result<void> {
263 self.recorder().consume_sload()?;
264 self.recorder().consume_sstore()?;
265
266 <Pallet<T>>::ensure_owner(contract_address, caller).map_err(dispatch_to_evm::<T>)?;
267 <Pallet<T>>::set_sponsoring_fee_limit(contract_address, fee_limit.into())
268 .map_err(dispatch_to_evm::<T>)?;
269 Ok(())
270 }
271
272 /// Get current contract sponsoring fee limit
273 /// @param contractAddress Contract to get sponsoring fee limit of
274 /// @return uint256 Maximum amount of fee that could be spent by single
275 /// transaction
276 fn get_sponsoring_fee_limit(&self, contract_address: address) -> Result<uint256> {
277 self.recorder().consume_sload()?;
278
279 Ok(get_sponsoring_fee_limit::<T>(contract_address))
280 }
252281
253 /// Is specified user present in contract allow list282 /// Is specified user present in contract allow list
254 /// @dev Contract owner always implicitly included283 /// @dev Contract owner always implicitly included
363392
364/// Bridge to pallet-sponsoring393/// Bridge to pallet-sponsoring
365pub struct HelpersContractSponsoring<T: Config>(PhantomData<*const T>);394pub struct HelpersContractSponsoring<T: Config>(PhantomData<*const T>);
366impl<T: Config> SponsorshipHandler<T::CrossAccountId, (H160, Vec<u8>)>395impl<T: Config> SponsorshipHandler<T::CrossAccountId, CallContext>
367 for HelpersContractSponsoring<T>396 for HelpersContractSponsoring<T>
368{397{
369 fn get_sponsor(who: &T::CrossAccountId, call: &(H160, Vec<u8>)) -> Option<T::CrossAccountId> {398 fn get_sponsor(
399 who: &T::CrossAccountId,
400 call_context: &CallContext,
401 ) -> Option<T::CrossAccountId> {
370 let (contract_address, _) = call;402 let contract_address = call_context.contract_address;
371 let mode = <Pallet<T>>::sponsoring_mode(*contract_address);403 let mode = <Pallet<T>>::sponsoring_mode(contract_address);
372 if mode == SponsoringModeT::Disabled {404 if mode == SponsoringModeT::Disabled {
373 return None;405 return None;
374 }406 }
375407
376 let sponsor = match <Pallet<T>>::get_sponsor(*contract_address) {408 let sponsor = match <Pallet<T>>::get_sponsor(contract_address) {
377 Some(sponsor) => sponsor,409 Some(sponsor) => sponsor,
378 None => return None,410 None => return None,
379 };411 };
380412
381 if mode == SponsoringModeT::Allowlisted413 if mode == SponsoringModeT::Allowlisted
382 && !<Pallet<T>>::allowed(*contract_address, *who.as_eth())414 && !<Pallet<T>>::allowed(contract_address, *who.as_eth())
383 {415 {
384 return None;416 return None;
385 }417 }
394 }426 }
395 }427 }
428
429 let sponsored_fee_limit = get_sponsoring_fee_limit::<T>(contract_address);
430
431 if call_context.max_fee > sponsored_fee_limit {
432 return None;
433 }
396434
397 <SponsorBasket<T>>::insert(contract_address, who.as_eth(), block_number);435 <SponsorBasket<T>>::insert(contract_address, who.as_eth(), block_number);
398436
399 Some(sponsor)437 Some(sponsor)
400 }438 }
401}439}
440
441fn get_sponsoring_fee_limit<T: Config>(contract_address: address) -> uint256 {
442 <SponsoringFeeLimit<T>>::get(contract_address)
443 .get(&0xffffffff)
444 .cloned()
445 .unwrap_or(U256::MAX)
446}
402447
403generate_stubgen!(contract_helpers_impl, ContractHelpersCall<()>, true);448generate_stubgen!(contract_helpers_impl, ContractHelpersCall<()>, true);
404generate_stubgen!(contract_helpers_iface, ContractHelpersCall<()>, false);449generate_stubgen!(contract_helpers_iface, ContractHelpersCall<()>, false);
modifiedpallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth
22pub use pallet::*;22pub use pallet::*;
23pub use eth::*;23pub use eth::*;
24use scale_info::TypeInfo;24use scale_info::TypeInfo;
25use frame_support::storage::bounded_btree_map::BoundedBTreeMap;
25pub mod eth;26pub mod eth;
27
28/// Maximum number of methods per contract that could have fee limit
29pub const MAX_FEE_LIMITED_METHODS: u32 = 5;
2630
27#[frame_support::pallet]31#[frame_support::pallet]
28pub mod pallet {32pub mod pallet {
29 pub use super::*;33 pub use super::*;
30 use crate::eth::ContractHelpersEvents;34 use crate::eth::ContractHelpersEvents;
31 use frame_support::pallet_prelude::*;35 use frame_support::pallet_prelude::*;
32 use pallet_evm_coder_substrate::DispatchResult;36 use pallet_evm_coder_substrate::DispatchResult;
33 use sp_core::H160;37 use sp_core::{H160, U256};
34 use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};38 use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};
35 use up_data_structs::SponsorshipState;39 use up_data_structs::SponsorshipState;
36 use evm_coder::ToLog;40 use evm_coder::ToLog;
58 /// No pending sponsor for contract.62 /// No pending sponsor for contract.
59 NoPendingSponsor,63 NoPendingSponsor,
64
65 /// Number of methods that sponsored limit is defined for exceeds maximum.
66 TooManyMethodsHaveSponsoredLimit,
60 }67 }
6168
62 #[pallet::pallet]69 #[pallet::pallet]
118 /// * **Key2** - sponsored user address.125 /// * **Key2** - sponsored user address.
119 /// * **Value** - last sponsored block number.126 /// * **Value** - last sponsored block number.
120 #[pallet::storage]127 #[pallet::storage]
121 pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<128 pub(super) type SponsoringFeeLimit<T: Config> = StorageMap<
129 Hasher = Twox128,
130 Key = H160,
131 Value = BoundedBTreeMap<u32, U256, ConstU32<MAX_FEE_LIMITED_METHODS>>,
132 QueryKind = ValueQuery,
133 >;
134
135 #[pallet::storage]
136 pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<
122 Hasher1 = Twox128,137 Hasher1 = Twox128,
123 Key1 = H160,138 Key1 = H160,
124 Hasher2 = Twox128,139 Hasher2 = Twox128,
355 <SponsoringRateLimit<T>>::insert(contract, rate_limit);370 <SponsoringRateLimit<T>>::insert(contract, rate_limit);
356 }371 }
372
373 /// Set maximum for gas limit of transaction
374 pub fn set_sponsoring_fee_limit(contract: H160, fee_limit: U256) -> DispatchResult {
375 <SponsoringFeeLimit<T>>::try_mutate(contract, |limits_map| {
376 limits_map
377 .try_insert(0xffffffff, fee_limit)
378 .map_err(|_| <Error<T>>::TooManyMethodsHaveSponsoredLimit)
379 })?;
380 Ok(())
381 }
357382
358 /// Is user added to allowlist, or he is owner of specified contract383 /// Is user added to allowlist, or he is owner of specified contract
359 pub fn allowed(contract: H160, user: H160) -> bool {384 pub fn allowed(contract: H160, user: H160) -> bool {
modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth
32}32}
3333
34/// @title Magic contract, which allows users to reconfigure other contracts34/// @title Magic contract, which allows users to reconfigure other contracts
35/// @dev the ERC-165 identifier for this interface is 0xd77fab7035/// @dev the ERC-165 identifier for this interface is 0x172cb4fb
36contract ContractHelpers is Dummy, ERC165, ContractHelpersEvents {36contract ContractHelpers is Dummy, ERC165, ContractHelpersEvents {
37 /// Get user, which deployed specified contract37 /// Get user, which deployed specified contract
38 /// @dev May return zero address in case if contract is deployed38 /// @dev May return zero address in case if contract is deployed
171 }171 }
172172
173 /// Get current contract sponsoring rate limit173 /// Get current contract sponsoring rate limit
174 /// @param contractAddress Contract to get sponsoring mode of174 /// @param contractAddress Contract to get sponsoring rate limit of
175 /// @return uint32 Amount of blocks between two sponsored transactions175 /// @return uint32 Amount of blocks between two sponsored transactions
176 /// @dev EVM selector for this function is: 0x610cfabd,176 /// @dev EVM selector for this function is: 0x610cfabd,
177 /// or in textual repr: getSponsoringRateLimit(address)177 /// or in textual repr: getSponsoringRateLimit(address)
203 dummy = 0;203 dummy = 0;
204 }204 }
205
206 /// Set contract sponsoring fee limit
207 /// @dev Sponsoring fee limit - is maximum fee that could be spent by
208 /// single transaction
209 /// @param contractAddress Contract to change sponsoring fee limit of
210 /// @param feeLimit Fee limit
211 /// @dev Only contract owner can change this setting
212 /// @dev EVM selector for this function is: 0x03aed665,
213 /// or in textual repr: setSponsoringFeeLimit(address,uint256)
214 function setSponsoringFeeLimit(address contractAddress, uint256 feeLimit)
215 public
216 {
217 require(false, stub_error);
218 contractAddress;
219 feeLimit;
220 dummy = 0;
221 }
222
223 /// Get current contract sponsoring fee limit
224 /// @param contractAddress Contract to get sponsoring fee limit of
225 /// @return uint256 Maximum amount of fee that could be spent by single
226 /// transaction
227 /// @dev EVM selector for this function is: 0xc3fdc9ee,
228 /// or in textual repr: getSponsoringFeeLimit(address)
229 function getSponsoringFeeLimit(address contractAddress)
230 public
231 view
232 returns (uint256)
233 {
234 require(false, stub_error);
235 contractAddress;
236 dummy;
237 return 0;
238 }
205239
206 /// Is specified user present in contract allow list240 /// Is specified user present in contract allow list
207 /// @dev Contract owner always implicitly included241 /// @dev Contract owner always implicitly included
modifiedpallets/evm-migration/Cargo.tomldiffbeforeafterboth
15sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }15sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
16sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }18pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
19fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2020
21[dependencies.codec]21[dependencies.codec]
22default-features = false22default-features = false
modifiedpallets/evm-transaction-payment/Cargo.tomldiffbeforeafterboth
14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
15sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }15sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
16sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
18fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }18fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
19pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
20up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }20up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }
21fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }21fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2222
23[dependencies.codec]23[dependencies.codec]
24default-features = false24default-features = false
modifiedpallets/evm-transaction-payment/src/lib.rsdiffbeforeafterboth
22use fp_evm::WithdrawReason;22use fp_evm::WithdrawReason;
23use frame_support::traits::IsSubType;23use frame_support::traits::IsSubType;
24pub use pallet::*;24pub use pallet::*;
25use pallet_evm::{EnsureAddressOrigin, account::CrossAccountId};25use pallet_evm::{account::CrossAccountId, EnsureAddressOrigin};
26use sp_core::H160;26use sp_core::{H160, U256};
27use sp_runtime::{TransactionOutcome, DispatchError};27use sp_runtime::{TransactionOutcome, DispatchError};
28use up_sponsorship::SponsorshipHandler;28use up_sponsorship::SponsorshipHandler;
2929
3333
34 use sp_std::vec::Vec;34 use sp_std::vec::Vec;
35
36 /// Contains call data
37 pub struct CallContext {
38 /// Contract address
39 pub contract_address: H160,
40 /// Transaction data
41 pub input: Vec<u8>,
42 /// Max fee for transaction - gasLimit * gasPrice
43 pub max_fee: U256,
44 }
3545
36 #[pallet::config]46 #[pallet::config]
37 pub trait Config: frame_system::Config + pallet_evm::account::Config {47 pub trait Config: frame_system::Config + pallet_evm::account::Config {
38 /// Loosly-coupled handlers for evm call sponsoring48 /// Loosly-coupled handlers for evm call sponsoring
39 type EvmSponsorshipHandler: SponsorshipHandler<Self::CrossAccountId, (H160, Vec<u8>)>;49 type EvmSponsorshipHandler: SponsorshipHandler<Self::CrossAccountId, CallContext>;
40 }50 }
4151
42 #[pallet::pallet]52 #[pallet::pallet]
49impl<T: Config> fp_evm::TransactionValidityHack<T::CrossAccountId> for TransactionValidityHack<T> {59impl<T: Config> fp_evm::TransactionValidityHack<T::CrossAccountId> for TransactionValidityHack<T> {
50 fn who_pays_fee(origin: H160, reason: &WithdrawReason) -> Option<T::CrossAccountId> {60 fn who_pays_fee(
61 origin: H160,
62 max_fee: U256,
63 reason: &WithdrawReason,
64 ) -> Option<T::CrossAccountId> {
51 match reason {65 match reason {
52 WithdrawReason::Call { target, input } => {66 WithdrawReason::Call { target, input } => {
53 let origin_sub = T::CrossAccountId::from_eth(origin);67 let origin_sub = T::CrossAccountId::from_eth(origin);
68 let call_context = CallContext {
69 contract_address: *target,
70 input: input.clone(),
71 max_fee,
72 };
54 T::EvmSponsorshipHandler::get_sponsor(&origin_sub, &(*target, input.clone()))73 T::EvmSponsorshipHandler::get_sponsor(&origin_sub, &call_context)
55 }74 }
56 _ => None,75 _ => None,
57 }76 }
71 source,90 source,
72 target,91 target,
73 input,92 input,
93 gas_limit,
94 max_fee_per_gas,
74 ..95 ..
75 } => {96 } => {
76 let _ = T::CallOrigin::ensure_address_origin(97 let _ = T::CallOrigin::ensure_address_origin(
79 )100 )
80 .ok()?;101 .ok()?;
81 let who = T::CrossAccountId::from_sub(who.clone());102 let who = T::CrossAccountId::from_sub(who.clone());
103 let max_fee = max_fee_per_gas.saturating_mul((*gas_limit).into());
104 let call_context = CallContext {
105 contract_address: *target,
106 input: input.clone(),
107 max_fee,
108 };
82 // Effects from EvmSponsorshipHandler are applied by pallet_evm::runner109 // Effects from EvmSponsorshipHandler are applied by pallet_evm::runner
83 // TODO: Should we implement simulation mode (test, but do not apply effects) in `up-sponsorship`?110 // TODO: Should we implement simulation mode (test, but do not apply effects) in `up-sponsorship`?
84 let sponsor = frame_support::storage::with_transaction(|| {111 let sponsor = frame_support::storage::with_transaction(|| {
85 TransactionOutcome::Rollback(Ok::<_, DispatchError>(112 TransactionOutcome::Rollback(Ok::<_, DispatchError>(
86 T::EvmSponsorshipHandler::get_sponsor(&who, &(*target, input.clone())),113 T::EvmSponsorshipHandler::get_sponsor(&who, &call_context),
87 ))114 ))
88 })115 })
89 // FIXME: it may fail with DispatchError in case of depth limit116 // FIXME: it may fail with DispatchError in case of depth limit
modifiedpallets/fungible/Cargo.tomldiffbeforeafterboth
23pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }23pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }
24ethereum = { version = "0.12.0", default-features = false }24ethereum = { version = "0.12.0", default-features = false }
25frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }25frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
26pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }26pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
27scale-info = { version = "2.0.1", default-features = false, features = [27scale-info = { version = "2.0.1", default-features = false, features = [
28 "derive",28 "derive",
29] }29] }
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
22}22}
2323
24/// @title A contract that allows you to work with collections.24/// @title A contract that allows you to work with collections.
25/// @dev the ERC-165 identifier for this interface is 0xe54be64025/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
26contract Collection is Dummy, ERC165 {26contract Collection is Dummy, ERC165 {
27 /// Set collection property.27 /// Set collection property.
28 ///28 ///
255 dummy = 0;255 dummy = 0;
256 }256 }
257
258 /// Checks that user allowed to operate with collection.
259 ///
260 /// @param user User address to check.
261 /// @dev EVM selector for this function is: 0xd63a8e11,
262 /// or in textual repr: allowed(address)
263 function allowed(address user) public view returns (bool) {
264 require(false, stub_error);
265 user;
266 dummy;
267 return false;
268 }
257269
258 /// Add the user to the allowed list.270 /// Add the user to the allowed list.
259 ///271 ///
266 dummy = 0;278 dummy = 0;
267 }279 }
280
281 /// Add substrate user to allowed list.
282 ///
283 /// @param user User substrate address.
284 /// @dev EVM selector for this function is: 0xd06ad267,
285 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
286 function addToCollectionAllowListSubstrate(uint256 user) public {
287 require(false, stub_error);
288 user;
289 dummy = 0;
290 }
268291
269 /// Remove the user from the allowed list.292 /// Remove the user from the allowed list.
270 ///293 ///
277 dummy = 0;300 dummy = 0;
278 }301 }
302
303 /// Remove substrate user from allowed list.
304 ///
305 /// @param user User substrate address.
306 /// @dev EVM selector for this function is: 0xa31913ed,
307 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
308 function removeFromCollectionAllowListSubstrate(uint256 user) public {
309 require(false, stub_error);
310 user;
311 dummy = 0;
312 }
279313
280 /// Switch permission for minting.314 /// Switch permission for minting.
281 ///315 ///
325 return "";359 return "";
326 }360 }
361
362 /// Get collection owner.
363 ///
364 /// @return Tuble with sponsor address and his substrate mirror.
365 /// If address is canonical then substrate mirror is zero and vice versa.
366 /// @dev EVM selector for this function is: 0xdf727d3b,
367 /// or in textual repr: collectionOwner()
368 function collectionOwner() public view returns (Tuple6 memory) {
369 require(false, stub_error);
370 dummy;
371 return Tuple6(0x0000000000000000000000000000000000000000, 0);
372 }
327373
328 /// Changes collection owner to another account374 /// Changes collection owner to another account
329 ///375 ///
modifiedpallets/nonfungible/Cargo.tomldiffbeforeafterboth
16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
20pallet-common = { default-features = false, path = '../common' }20pallet-common = { default-features = false, path = '../common' }
21pallet-structure = { default-features = false, path = '../structure' }21pallet-structure = { default-features = false, path = '../structure' }
22up-data-structs = { default-features = false, path = '../../primitives/data-structs' }22up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
99}99}
100100
101/// @title A contract that allows you to work with collections.101/// @title A contract that allows you to work with collections.
102/// @dev the ERC-165 identifier for this interface is 0xe54be640102/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
103contract Collection is Dummy, ERC165 {103contract Collection is Dummy, ERC165 {
104 /// Set collection property.104 /// Set collection property.
105 ///105 ///
332 dummy = 0;332 dummy = 0;
333 }333 }
334
335 /// Checks that user allowed to operate with collection.
336 ///
337 /// @param user User address to check.
338 /// @dev EVM selector for this function is: 0xd63a8e11,
339 /// or in textual repr: allowed(address)
340 function allowed(address user) public view returns (bool) {
341 require(false, stub_error);
342 user;
343 dummy;
344 return false;
345 }
334346
335 /// Add the user to the allowed list.347 /// Add the user to the allowed list.
336 ///348 ///
343 dummy = 0;355 dummy = 0;
344 }356 }
357
358 /// Add substrate user to allowed list.
359 ///
360 /// @param user User substrate address.
361 /// @dev EVM selector for this function is: 0xd06ad267,
362 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
363 function addToCollectionAllowListSubstrate(uint256 user) public {
364 require(false, stub_error);
365 user;
366 dummy = 0;
367 }
345368
346 /// Remove the user from the allowed list.369 /// Remove the user from the allowed list.
347 ///370 ///
354 dummy = 0;377 dummy = 0;
355 }378 }
379
380 /// Remove substrate user from allowed list.
381 ///
382 /// @param user User substrate address.
383 /// @dev EVM selector for this function is: 0xa31913ed,
384 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
385 function removeFromCollectionAllowListSubstrate(uint256 user) public {
386 require(false, stub_error);
387 user;
388 dummy = 0;
389 }
356390
357 /// Switch permission for minting.391 /// Switch permission for minting.
358 ///392 ///
402 return "";436 return "";
403 }437 }
438
439 /// Get collection owner.
440 ///
441 /// @return Tuble with sponsor address and his substrate mirror.
442 /// If address is canonical then substrate mirror is zero and vice versa.
443 /// @dev EVM selector for this function is: 0xdf727d3b,
444 /// or in textual repr: collectionOwner()
445 function collectionOwner() public view returns (Tuple17 memory) {
446 require(false, stub_error);
447 dummy;
448 return Tuple17(0x0000000000000000000000000000000000000000, 0);
449 }
404450
405 /// Changes collection owner to another account451 /// Changes collection owner to another account
406 ///452 ///
modifiedpallets/proxy-rmrk-core/Cargo.tomldiffbeforeafterboth
20pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }20pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
21pallet-structure = { default-features = false, path = "../../pallets/structure" }21pallet-structure = { default-features = false, path = "../../pallets/structure" }
22up-data-structs = { default-features = false, path = '../../primitives/data-structs' }22up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
23pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }23pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
24frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }24frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
25rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }25rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }
26scale-info = { version = "2.0.1", default-features = false, features = [26scale-info = { version = "2.0.1", default-features = false, features = [
modifiedpallets/proxy-rmrk-equip/Cargo.tomldiffbeforeafterboth
19pallet-common = { default-features = false, path = '../common' }19pallet-common = { default-features = false, path = '../common' }
20pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }20pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }22pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
23frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }23frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
24rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }24rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }
25scale-info = { version = "2.0.1", default-features = false, features = [25scale-info = { version = "2.0.1", default-features = false, features = [
modifiedpallets/refungible/Cargo.tomldiffbeforeafterboth
16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
20evm-coder = { default-features = false, path = '../../crates/evm-coder' }20evm-coder = { default-features = false, path = '../../crates/evm-coder' }
21pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }21pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
22pallet-common = { default-features = false, path = '../common' }22pallet-common = { default-features = false, path = '../common' }
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
99}99}
100100
101/// @title A contract that allows you to work with collections.101/// @title A contract that allows you to work with collections.
102/// @dev the ERC-165 identifier for this interface is 0xe54be640102/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
103contract Collection is Dummy, ERC165 {103contract Collection is Dummy, ERC165 {
104 /// Set collection property.104 /// Set collection property.
105 ///105 ///
332 dummy = 0;332 dummy = 0;
333 }333 }
334
335 /// Checks that user allowed to operate with collection.
336 ///
337 /// @param user User address to check.
338 /// @dev EVM selector for this function is: 0xd63a8e11,
339 /// or in textual repr: allowed(address)
340 function allowed(address user) public view returns (bool) {
341 require(false, stub_error);
342 user;
343 dummy;
344 return false;
345 }
334346
335 /// Add the user to the allowed list.347 /// Add the user to the allowed list.
336 ///348 ///
343 dummy = 0;355 dummy = 0;
344 }356 }
357
358 /// Add substrate user to allowed list.
359 ///
360 /// @param user User substrate address.
361 /// @dev EVM selector for this function is: 0xd06ad267,
362 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
363 function addToCollectionAllowListSubstrate(uint256 user) public {
364 require(false, stub_error);
365 user;
366 dummy = 0;
367 }
345368
346 /// Remove the user from the allowed list.369 /// Remove the user from the allowed list.
347 ///370 ///
354 dummy = 0;377 dummy = 0;
355 }378 }
379
380 /// Remove substrate user from allowed list.
381 ///
382 /// @param user User substrate address.
383 /// @dev EVM selector for this function is: 0xa31913ed,
384 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
385 function removeFromCollectionAllowListSubstrate(uint256 user) public {
386 require(false, stub_error);
387 user;
388 dummy = 0;
389 }
356390
357 /// Switch permission for minting.391 /// Switch permission for minting.
358 ///392 ///
402 return "";436 return "";
403 }437 }
438
439 /// Get collection owner.
440 ///
441 /// @return Tuble with sponsor address and his substrate mirror.
442 /// If address is canonical then substrate mirror is zero and vice versa.
443 /// @dev EVM selector for this function is: 0xdf727d3b,
444 /// or in textual repr: collectionOwner()
445 function collectionOwner() public view returns (Tuple17 memory) {
446 require(false, stub_error);
447 dummy;
448 return Tuple17(0x0000000000000000000000000000000000000000, 0);
449 }
404450
405 /// Changes collection owner to another account451 /// Changes collection owner to another account
406 ///452 ///
modifiedpallets/structure/Cargo.tomldiffbeforeafterboth
16 "derive",16 "derive",
17] }17] }
18up-data-structs = { path = "../../primitives/data-structs", default-features = false }18up-data-structs = { path = "../../primitives/data-structs", default-features = false }
19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2020
21[features]21[features]
22default = ["std"]22default = ["std"]
modifiedpallets/unique/CHANGELOG.mddiffbeforeafterboth
44
5<!-- bureaucrate goes here -->5<!-- bureaucrate goes here -->
66
7## [v0.2.0] 2022-09-13
8
9### Changes
10- Change **collectionHelper** method `createRefungibleCollection` to `createRFTCollection`,
11
7## [v0.1.4] 2022-09-0512## [v0.1.4] 2022-09-05
813
9### Added14### Added
modifiedpallets/unique/Cargo.tomldiffbeforeafterboth
9license = 'GPLv3'9license = 'GPLv3'
10name = 'pallet-unique'10name = 'pallet-unique'
11repository = 'https://github.com/UniqueNetwork/unique-chain'11repository = 'https://github.com/UniqueNetwork/unique-chain'
12version = "0.1.4"12version = "0.2.0"
1313
14[package.metadata.docs.rs]14[package.metadata.docs.rs]
15targets = ['x86_64-unknown-linux-gnu']15targets = ['x86_64-unknown-linux-gnu']
98scale-info = { version = "2.0.1", default-features = false, features = [98scale-info = { version = "2.0.1", default-features = false, features = [
99 "derive",99 "derive",
100] }100] }
101pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }101pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
102pallet-common = { default-features = false, path = "../common" }102pallet-common = { default-features = false, path = "../common" }
103evm-coder = { default-features = false, path = '../../crates/evm-coder' }103evm-coder = { default-features = false, path = '../../crates/evm-coder' }
104pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }104pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
modifiedpallets/unique/src/eth/mod.rsdiffbeforeafterboth
21use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};21use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};
22use frame_support::traits::Get;22use frame_support::traits::Get;
23use pallet_common::{23use pallet_common::{
24 CollectionById, CollectionHandle,24 CollectionById,
25 dispatch::CollectionDispatch,25 dispatch::CollectionDispatch,
26 erc::{26 erc::{
27 CollectionHelpersEvents,27 CollectionHelpersEvents,
28 static_property::{key, value as property_value},28 static_property::{key, value as property_value},
29 },29 },
30 Pallet as PalletCommon,
31};30};
32use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};31use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
33use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};32use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};
34use pallet_evm_coder_substrate::dispatch_to_evm;
35use up_data_structs::{33use up_data_structs::{
36 CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,34 CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,
37 CollectionMode, PropertyKeyPermission, PropertyPermission, PropertyScope, PropertyValue,35 CollectionMode, PropertyValue,
38};36};
3937
40use crate::{Config, SelfWeightOf, weights::WeightInfo};38use crate::{Config, SelfWeightOf, weights::WeightInfo};
4139
42use sp_std::{vec, vec::Vec};40use sp_std::vec::Vec;
43use alloc::format;41use alloc::format;
4442
45/// See [`CollectionHelpersCall`]43/// See [`CollectionHelpersCall`]
245 }243 }
246244
247 #[weight(<SelfWeightOf<T>>::create_collection())]245 #[weight(<SelfWeightOf<T>>::create_collection())]
246 #[solidity(rename_selector = "createRFTCollection")]
248 fn create_refungible_collection(247 fn create_refungible_collection(
249 &mut self,248 &mut self,
250 caller: caller,249 caller: caller,
modifiedpallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth
30}23}
3124
32/// @title Contract, which allows users to operate with collections25/// @title Contract, which allows users to operate with collections
33/// @dev the ERC-165 identifier for this interface is 0x675f307426/// @dev the ERC-165 identifier for this interface is 0x88ee8ef1
34contract CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {27contract CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {
35 /// Create an NFT collection28 /// Create an NFT collection
36 /// @param name Name of the collection29 /// @param name Name of the collection
69 return 0x0000000000000000000000000000000000000000;62 return 0x0000000000000000000000000000000000000000;
70 }63 }
7164
72 /// @dev EVM selector for this function is: 0x44a68ad5,65 /// @dev EVM selector for this function is: 0xab173450,
73 /// or in textual repr: createRefungibleCollection(string,string,string)66 /// or in textual repr: createRFTCollection(string,string,string)
74 function createRefungibleCollection(67 function createRFTCollection(
75 string memory name,68 string memory name,
76 string memory description,69 string memory description,
77 string memory tokenPrefix70 string memory tokenPrefix
modifiedprimitives/app_promotion_rpc/Cargo.tomldiffbeforeafterboth
14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
15sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }15sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
1818
19[features]19[features]
20default = ["std"]20default = ["std"]
modifiedprimitives/common/Cargo.tomldiffbeforeafterboth
48[dependencies.fp-rpc]48[dependencies.fp-rpc]
49default-features = false49default-features = false
50git = "https://github.com/uniquenetwork/frontier"50git = "https://github.com/uniquenetwork/frontier"
51branch = "unique-polkadot-v0.9.27"51branch = "unique-polkadot-v0.9.27-fee-limit"
5252
53[dependencies.pallet-evm]53[dependencies.pallet-evm]
54default-features = false54default-features = false
55git = "https://github.com/uniquenetwork/frontier"55git = "https://github.com/uniquenetwork/frontier"
56branch = "unique-polkadot-v0.9.27"56branch = "unique-polkadot-v0.9.27-fee-limit"
5757
modifiedprimitives/data-structs/Cargo.tomldiffbeforeafterboth
25sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }25sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
26derivative = { version = "2.2.0", features = ["use_core"] }26derivative = { version = "2.2.0", features = ["use_core"] }
27struct-versioning = { path = "../../crates/struct-versioning" }27struct-versioning = { path = "../../crates/struct-versioning" }
28pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }28pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
29rmrk-traits = { default-features = false, path = "../rmrk-traits" }29rmrk-traits = { default-features = false, path = "../rmrk-traits" }
3030
31[features]31[features]
modifiedprimitives/rpc/Cargo.tomldiffbeforeafterboth
14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }14sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
15sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }15sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }17pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
1818
19[features]19[features]
20default = ["std"]20default = ["std"]
modifiedruntime/common/config/sponsoring.rsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17use frame_support::parameter_types;
18use crate::{17use crate::{
19 runtime_common::{sponsoring::UniqueSponsorshipHandler},18 runtime_common::{sponsoring::UniqueSponsorshipHandler},
20 Runtime,19 Runtime,
21};20};
21use frame_support::parameter_types;
22use sp_core::U256;
22use up_common::{types::BlockNumber, constants::*};23use up_common::{constants::*, types::BlockNumber};
2324
24parameter_types! {25parameter_types! {
25 pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS;26 pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS;
27 pub const DefaultSponsoringFeeLimit: U256 = U256::MAX;
26}28}
2729
28type SponsorshipHandler = (30type SponsorshipHandler = (
modifiedruntime/common/ethereum/sponsoring.rsdiffbeforeafterboth
1616
17//! Implements EVM sponsoring logic via TransactionValidityHack17//! Implements EVM sponsoring logic via TransactionValidityHack
1818
19use core::{convert::TryInto, marker::PhantomData};
19use evm_coder::{Call, abi::AbiReader};20use evm_coder::{Call, abi::AbiReader};
20use pallet_common::{CollectionHandle, eth::map_eth_to_id};21use pallet_common::{CollectionHandle, eth::map_eth_to_id};
21use sp_core::H160;22use pallet_evm::account::CrossAccountId;
23use pallet_evm_transaction_payment::CallContext;
22use sp_std::prelude::*;24use pallet_nonfungible::{
25 Config as NonfungibleConfig,
26 erc::{
27 UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721MintableCall, ERC721Call,
28 TokenPropertiesCall,
29 },
30};
23use up_sponsorship::SponsorshipHandler;31use pallet_fungible::{
32 Config as FungibleConfig,
33 erc::{UniqueFungibleCall, ERC20Call},
34};
24use core::marker::PhantomData;35use pallet_refungible::Config as RefungibleConfig;
25use core::convert::TryInto;36use pallet_unique::Config as UniqueConfig;
26use pallet_evm::account::CrossAccountId;37use sp_std::prelude::*;
27use up_data_structs::{TokenId, CreateItemData, CreateNftData, CollectionMode};38use up_data_structs::{CollectionMode, CreateItemData, CreateNftData, TokenId};
28use pallet_unique::Config as UniqueConfig;39use up_sponsorship::SponsorshipHandler;
2940
30use crate::{Runtime, runtime_common::sponsoring::*};41use crate::{Runtime, runtime_common::sponsoring::*};
31
32use pallet_nonfungible::erc::{
33 UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721MintableCall, ERC721Call, TokenPropertiesCall,
34};
35use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};
36use pallet_fungible::Config as FungibleConfig;
37use pallet_nonfungible::Config as NonfungibleConfig;
38use pallet_refungible::Config as RefungibleConfig;
3942
40pub type EvmSponsorshipHandler = (43pub type EvmSponsorshipHandler = (
41 UniqueEthSponsorshipHandler<Runtime>,44 UniqueEthSponsorshipHandler<Runtime>,
4447
45pub struct UniqueEthSponsorshipHandler<T: UniqueConfig>(PhantomData<*const T>);48pub struct UniqueEthSponsorshipHandler<T: UniqueConfig>(PhantomData<*const T>);
46impl<T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig>49impl<T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig>
47 SponsorshipHandler<T::CrossAccountId, (H160, Vec<u8>)> for UniqueEthSponsorshipHandler<T>50 SponsorshipHandler<T::CrossAccountId, CallContext> for UniqueEthSponsorshipHandler<T>
48{51{
49 fn get_sponsor(who: &T::CrossAccountId, call: &(H160, Vec<u8>)) -> Option<T::CrossAccountId> {52 fn get_sponsor(
53 who: &T::CrossAccountId,
54 call_context: &CallContext,
55 ) -> Option<T::CrossAccountId> {
50 let collection_id = map_eth_to_id(&call.0)?;56 let collection_id = map_eth_to_id(&call_context.contract_address)?;
51 let collection = <CollectionHandle<T>>::new(collection_id)?;57 let collection = <CollectionHandle<T>>::new(collection_id)?;
52 let sponsor = collection.sponsorship.sponsor()?.clone();58 let sponsor = collection.sponsorship.sponsor()?.clone();
53 let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;59 let (method_id, mut reader) = AbiReader::new_call(&call_context.input).ok()?;
54 Some(T::CrossAccountId::from_sub(match &collection.mode {60 Some(T::CrossAccountId::from_sub(match &collection.mode {
55 CollectionMode::NFT => {61 CollectionMode::NFT => {
56 let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;62 let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;
modifiedruntime/opal/Cargo.tomldiffbeforeafterboth
441up-rpc = { path = "../../primitives/rpc", default-features = false }441up-rpc = { path = "../../primitives/rpc", default-features = false }
442app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}442app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}
443rmrk-rpc = { path = "../../primitives/rmrk-rpc", default-features = false }443rmrk-rpc = { path = "../../primitives/rmrk-rpc", default-features = false }
444fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }444fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
445pallet-inflation = { path = '../../pallets/inflation', default-features = false }445pallet-inflation = { path = '../../pallets/inflation', default-features = false }
446pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }446pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
447up-data-structs = { path = '../../primitives/data-structs', default-features = false }447up-data-structs = { path = '../../primitives/data-structs', default-features = false }
460pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }460pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
461pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }461pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
462pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }462pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
463pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }463pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
464pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }464pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
465pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }465pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
466fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }466fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
467fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }467fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
468evm-coder = { default-features = false, path = '../../crates/evm-coder' }468evm-coder = { default-features = false, path = '../../crates/evm-coder' }
469up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }469up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }
470pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }470pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
modifiedruntime/quartz/Cargo.tomldiffbeforeafterboth
446pallet-unique = { path = '../../pallets/unique', default-features = false }446pallet-unique = { path = '../../pallets/unique', default-features = false }
447up-rpc = { path = "../../primitives/rpc", default-features = false }447up-rpc = { path = "../../primitives/rpc", default-features = false }
448app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}448app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false}
449fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }449fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
450pallet-inflation = { path = '../../pallets/inflation', default-features = false }450pallet-inflation = { path = '../../pallets/inflation', default-features = false }
451pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }451pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
452up-data-structs = { path = '../../primitives/data-structs', default-features = false }452up-data-structs = { path = '../../primitives/data-structs', default-features = false }
465pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }465pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
466pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }466pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
467pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }467pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
468pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }468pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
469pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }469pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
470pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }470pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
471fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }471fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
472fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }472fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
473evm-coder = { default-features = false, path = '../../crates/evm-coder' }473evm-coder = { default-features = false, path = '../../crates/evm-coder' }
474up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }474up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }
475pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }475pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
modifiedruntime/tests/Cargo.tomldiffbeforeafterboth
16sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }16sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
17sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }17sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
1818
19fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }19fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
2020
21frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }21frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
22frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }22frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
25pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }25pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
26pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }26pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
2727
28pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }28pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
29pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }29pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
3030
31pallet-common = { path = '../../pallets/common' }31pallet-common = { path = '../../pallets/common' }
32pallet-structure = { path = '../../pallets/structure' }32pallet-structure = { path = '../../pallets/structure' }
43scale-info = "*"43scale-info = "*"
4444
45evm-coder = { default-features = false, path = '../../crates/evm-coder' }45evm-coder = { default-features = false, path = '../../crates/evm-coder' }
46up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }46up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.27" }
4747
modifiedruntime/unique/Cargo.tomldiffbeforeafterboth
456pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }456pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
457pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }457pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
458pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }458pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
459pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }459pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
460pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }460pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
461pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }461pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
462fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }462fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
463fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }463fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
464fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" }464fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27-fee-limit" }
465evm-coder = { default-features = false, path = '../../crates/evm-coder' }465evm-coder = { default-features = false, path = '../../crates/evm-coder' }
466up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }466up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' }
467pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }467pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
modifiedtests/src/eth/allowlist.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {IKeyringPair} from '@polkadot/types/types';
17import {expect} from 'chai';18import {expect} from 'chai';
19import {isAllowlisted, normalizeAccountId} from '../util/helpers';
18import {contractHelpers, createEthAccountWithBalance, deployFlipper, itWeb3} from './util/helpers';20import {
21 contractHelpers,
22 createEthAccount,
23 createEthAccountWithBalance,
24 deployFlipper,
25 evmCollection,
26 evmCollectionHelpers,
27 getCollectionAddressFromResult,
28 itWeb3,
29} from './util/helpers';
30import {itEth, usingEthPlaygrounds} from './util/playgrounds';
1931
20describe('EVM allowlist', () => {32describe('EVM contract allowlist', () => {
21 itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => {33 itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => {
22 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);34 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
23 const flipper = await deployFlipper(web3, owner);35 const flipper = await deployFlipper(web3, owner);
59 });71 });
60});72});
73
74describe('EVM collection allowlist', () => {
75 let donor: IKeyringPair;
76
77 before(async function() {
78 await usingEthPlaygrounds(async (_helper, privateKey) => {
79 donor = privateKey('//Alice');
80 });
81 });
82
83 itEth('Collection allowlist can be added and removed by [eth] address', async ({helper}) => {
84 const owner = await helper.eth.createAccountWithBalance(donor);
85 const user = helper.eth.createAccount();
86
87 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
88 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
89
90 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
91 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
92 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
93
94 await collectionEvm.methods.removeFromCollectionAllowList(user).send({from: owner});
95 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
96 });
97
98 itEth('Collection allowlist can be added and removed by [sub] address', async ({helper}) => {
99 const owner = await helper.eth.createAccountWithBalance(donor);
100 const user = donor;
101
102 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
103 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
104
105 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
106 await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
107 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
108
109 await collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
110 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
111 });
112
113 itEth('Collection allowlist can not be add and remove [eth] address by not owner', async ({helper}) => {
114 const owner = await helper.eth.createAccountWithBalance(donor);
115 const notOwner = await helper.eth.createAccountWithBalance(donor);
116 const user = helper.eth.createAccount();
117
118 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
119 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
120
121 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
122 await expect(collectionEvm.methods.addToCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');
123 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
124 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
125
126 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
127 await expect(collectionEvm.methods.removeFromCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');
128 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
129 });
130
131 itEth('Collection allowlist can not be add and remove [sub] address by not owner', async ({helper}) => {
132 const owner = await helper.eth.createAccountWithBalance(donor);
133 const notOwner = await helper.eth.createAccountWithBalance(donor);
134 const user = donor;
135
136 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
137 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
138
139 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
140 await expect(collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');
141 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
142 await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
143
144 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
145 await expect(collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');
146 expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
147 });
148});
61149
modifiedtests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth
21}18}
2219
23/// @title Contract, which allows users to operate with collections20/// @title Contract, which allows users to operate with collections
24/// @dev the ERC-165 identifier for this interface is 0x675f307421/// @dev the ERC-165 identifier for this interface is 0x88ee8ef1
25interface CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {22interface CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {
26 /// Create an NFT collection23 /// Create an NFT collection
27 /// @param name Name of the collection24 /// @param name Name of the collection
45 string memory baseUri42 string memory baseUri
46 ) external returns (address);43 ) external returns (address);
4744
48 /// @dev EVM selector for this function is: 0x44a68ad5,45 /// @dev EVM selector for this function is: 0xab173450,
49 /// or in textual repr: createRefungibleCollection(string,string,string)46 /// or in textual repr: createRFTCollection(string,string,string)
50 function createRefungibleCollection(47 function createRFTCollection(
51 string memory name,48 string memory name,
52 string memory description,49 string memory description,
53 string memory tokenPrefix50 string memory tokenPrefix
modifiedtests/src/eth/api/ContractHelpers.soldiffbeforeafterboth
23}23}
2424
25/// @title Magic contract, which allows users to reconfigure other contracts25/// @title Magic contract, which allows users to reconfigure other contracts
26/// @dev the ERC-165 identifier for this interface is 0xd77fab7026/// @dev the ERC-165 identifier for this interface is 0x172cb4fb
27interface ContractHelpers is Dummy, ERC165, ContractHelpersEvents {27interface ContractHelpers is Dummy, ERC165, ContractHelpersEvents {
28 /// Get user, which deployed specified contract28 /// Get user, which deployed specified contract
29 /// @dev May return zero address in case if contract is deployed29 /// @dev May return zero address in case if contract is deployed
111 function setSponsoringMode(address contractAddress, uint8 mode) external;111 function setSponsoringMode(address contractAddress, uint8 mode) external;
112112
113 /// Get current contract sponsoring rate limit113 /// Get current contract sponsoring rate limit
114 /// @param contractAddress Contract to get sponsoring mode of114 /// @param contractAddress Contract to get sponsoring rate limit of
115 /// @return uint32 Amount of blocks between two sponsored transactions115 /// @return uint32 Amount of blocks between two sponsored transactions
116 /// @dev EVM selector for this function is: 0x610cfabd,116 /// @dev EVM selector for this function is: 0x610cfabd,
117 /// or in textual repr: getSponsoringRateLimit(address)117 /// or in textual repr: getSponsoringRateLimit(address)
131 function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)131 function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)
132 external;132 external;
133
134 /// Set contract sponsoring fee limit
135 /// @dev Sponsoring fee limit - is maximum fee that could be spent by
136 /// single transaction
137 /// @param contractAddress Contract to change sponsoring fee limit of
138 /// @param feeLimit Fee limit
139 /// @dev Only contract owner can change this setting
140 /// @dev EVM selector for this function is: 0x03aed665,
141 /// or in textual repr: setSponsoringFeeLimit(address,uint256)
142 function setSponsoringFeeLimit(address contractAddress, uint256 feeLimit)
143 external;
144
145 /// Get current contract sponsoring fee limit
146 /// @param contractAddress Contract to get sponsoring fee limit of
147 /// @return uint256 Maximum amount of fee that could be spent by single
148 /// transaction
149 /// @dev EVM selector for this function is: 0xc3fdc9ee,
150 /// or in textual repr: getSponsoringFeeLimit(address)
151 function getSponsoringFeeLimit(address contractAddress)
152 external
153 view
154 returns (uint256);
133155
134 /// Is specified user present in contract allow list156 /// Is specified user present in contract allow list
135 /// @dev Contract owner always implicitly included157 /// @dev Contract owner always implicitly included
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
13}13}
1414
15/// @title A contract that allows you to work with collections.15/// @title A contract that allows you to work with collections.
16/// @dev the ERC-165 identifier for this interface is 0xe54be64016/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
17interface Collection is Dummy, ERC165 {17interface Collection is Dummy, ERC165 {
18 /// Set collection property.18 /// Set collection property.
19 ///19 ///
164 /// or in textual repr: setCollectionAccess(uint8)164 /// or in textual repr: setCollectionAccess(uint8)
165 function setCollectionAccess(uint8 mode) external;165 function setCollectionAccess(uint8 mode) external;
166
167 /// Checks that user allowed to operate with collection.
168 ///
169 /// @param user User address to check.
170 /// @dev EVM selector for this function is: 0xd63a8e11,
171 /// or in textual repr: allowed(address)
172 function allowed(address user) external view returns (bool);
166173
167 /// Add the user to the allowed list.174 /// Add the user to the allowed list.
168 ///175 ///
171 /// or in textual repr: addToCollectionAllowList(address)178 /// or in textual repr: addToCollectionAllowList(address)
172 function addToCollectionAllowList(address user) external;179 function addToCollectionAllowList(address user) external;
180
181 /// Add substrate user to allowed list.
182 ///
183 /// @param user User substrate address.
184 /// @dev EVM selector for this function is: 0xd06ad267,
185 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
186 function addToCollectionAllowListSubstrate(uint256 user) external;
173187
174 /// Remove the user from the allowed list.188 /// Remove the user from the allowed list.
175 ///189 ///
178 /// or in textual repr: removeFromCollectionAllowList(address)192 /// or in textual repr: removeFromCollectionAllowList(address)
179 function removeFromCollectionAllowList(address user) external;193 function removeFromCollectionAllowList(address user) external;
194
195 /// Remove substrate user from allowed list.
196 ///
197 /// @param user User substrate address.
198 /// @dev EVM selector for this function is: 0xa31913ed,
199 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
200 function removeFromCollectionAllowListSubstrate(uint256 user) external;
180201
181 /// Switch permission for minting.202 /// Switch permission for minting.
182 ///203 ///
208 /// or in textual repr: uniqueCollectionType()229 /// or in textual repr: uniqueCollectionType()
209 function uniqueCollectionType() external returns (string memory);230 function uniqueCollectionType() external returns (string memory);
231
232 /// Get collection owner.
233 ///
234 /// @return Tuble with sponsor address and his substrate mirror.
235 /// If address is canonical then substrate mirror is zero and vice versa.
236 /// @dev EVM selector for this function is: 0xdf727d3b,
237 /// or in textual repr: collectionOwner()
238 function collectionOwner() external view returns (Tuple6 memory);
210239
211 /// Changes collection owner to another account240 /// Changes collection owner to another account
212 ///241 ///
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
65}65}
6666
67/// @title A contract that allows you to work with collections.67/// @title A contract that allows you to work with collections.
68/// @dev the ERC-165 identifier for this interface is 0xe54be64068/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
69interface Collection is Dummy, ERC165 {69interface Collection is Dummy, ERC165 {
70 /// Set collection property.70 /// Set collection property.
71 ///71 ///
216 /// or in textual repr: setCollectionAccess(uint8)216 /// or in textual repr: setCollectionAccess(uint8)
217 function setCollectionAccess(uint8 mode) external;217 function setCollectionAccess(uint8 mode) external;
218
219 /// Checks that user allowed to operate with collection.
220 ///
221 /// @param user User address to check.
222 /// @dev EVM selector for this function is: 0xd63a8e11,
223 /// or in textual repr: allowed(address)
224 function allowed(address user) external view returns (bool);
218225
219 /// Add the user to the allowed list.226 /// Add the user to the allowed list.
220 ///227 ///
223 /// or in textual repr: addToCollectionAllowList(address)230 /// or in textual repr: addToCollectionAllowList(address)
224 function addToCollectionAllowList(address user) external;231 function addToCollectionAllowList(address user) external;
232
233 /// Add substrate user to allowed list.
234 ///
235 /// @param user User substrate address.
236 /// @dev EVM selector for this function is: 0xd06ad267,
237 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
238 function addToCollectionAllowListSubstrate(uint256 user) external;
225239
226 /// Remove the user from the allowed list.240 /// Remove the user from the allowed list.
227 ///241 ///
230 /// or in textual repr: removeFromCollectionAllowList(address)244 /// or in textual repr: removeFromCollectionAllowList(address)
231 function removeFromCollectionAllowList(address user) external;245 function removeFromCollectionAllowList(address user) external;
246
247 /// Remove substrate user from allowed list.
248 ///
249 /// @param user User substrate address.
250 /// @dev EVM selector for this function is: 0xa31913ed,
251 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
252 function removeFromCollectionAllowListSubstrate(uint256 user) external;
232253
233 /// Switch permission for minting.254 /// Switch permission for minting.
234 ///255 ///
260 /// or in textual repr: uniqueCollectionType()281 /// or in textual repr: uniqueCollectionType()
261 function uniqueCollectionType() external returns (string memory);282 function uniqueCollectionType() external returns (string memory);
283
284 /// Get collection owner.
285 ///
286 /// @return Tuble with sponsor address and his substrate mirror.
287 /// If address is canonical then substrate mirror is zero and vice versa.
288 /// @dev EVM selector for this function is: 0xdf727d3b,
289 /// or in textual repr: collectionOwner()
290 function collectionOwner() external view returns (Tuple17 memory);
262291
263 /// Changes collection owner to another account292 /// Changes collection owner to another account
264 ///293 ///
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
65}65}
6666
67/// @title A contract that allows you to work with collections.67/// @title A contract that allows you to work with collections.
68/// @dev the ERC-165 identifier for this interface is 0xe54be64068/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
69interface Collection is Dummy, ERC165 {69interface Collection is Dummy, ERC165 {
70 /// Set collection property.70 /// Set collection property.
71 ///71 ///
216 /// or in textual repr: setCollectionAccess(uint8)216 /// or in textual repr: setCollectionAccess(uint8)
217 function setCollectionAccess(uint8 mode) external;217 function setCollectionAccess(uint8 mode) external;
218
219 /// Checks that user allowed to operate with collection.
220 ///
221 /// @param user User address to check.
222 /// @dev EVM selector for this function is: 0xd63a8e11,
223 /// or in textual repr: allowed(address)
224 function allowed(address user) external view returns (bool);
218225
219 /// Add the user to the allowed list.226 /// Add the user to the allowed list.
220 ///227 ///
223 /// or in textual repr: addToCollectionAllowList(address)230 /// or in textual repr: addToCollectionAllowList(address)
224 function addToCollectionAllowList(address user) external;231 function addToCollectionAllowList(address user) external;
232
233 /// Add substrate user to allowed list.
234 ///
235 /// @param user User substrate address.
236 /// @dev EVM selector for this function is: 0xd06ad267,
237 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
238 function addToCollectionAllowListSubstrate(uint256 user) external;
225239
226 /// Remove the user from the allowed list.240 /// Remove the user from the allowed list.
227 ///241 ///
230 /// or in textual repr: removeFromCollectionAllowList(address)244 /// or in textual repr: removeFromCollectionAllowList(address)
231 function removeFromCollectionAllowList(address user) external;245 function removeFromCollectionAllowList(address user) external;
246
247 /// Remove substrate user from allowed list.
248 ///
249 /// @param user User substrate address.
250 /// @dev EVM selector for this function is: 0xa31913ed,
251 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
252 function removeFromCollectionAllowListSubstrate(uint256 user) external;
232253
233 /// Switch permission for minting.254 /// Switch permission for minting.
234 ///255 ///
260 /// or in textual repr: uniqueCollectionType()281 /// or in textual repr: uniqueCollectionType()
261 function uniqueCollectionType() external returns (string memory);282 function uniqueCollectionType() external returns (string memory);
283
284 /// Get collection owner.
285 ///
286 /// @return Tuble with sponsor address and his substrate mirror.
287 /// If address is canonical then substrate mirror is zero and vice versa.
288 /// @dev EVM selector for this function is: 0xdf727d3b,
289 /// or in textual repr: collectionOwner()
290 function collectionOwner() external view returns (Tuple17 memory);
262291
263 /// Changes collection owner to another account292 /// Changes collection owner to another account
264 ///293 ///
modifiedtests/src/eth/collectionHelpersAbi.jsondiffbeforeafterboth
59 { "internalType": "string", "name": "description", "type": "string" },59 { "internalType": "string", "name": "description", "type": "string" },
60 { "internalType": "string", "name": "tokenPrefix", "type": "string" }60 { "internalType": "string", "name": "tokenPrefix", "type": "string" }
61 ],61 ],
62 "name": "createRefungibleCollection",62 "name": "createRFTCollection",
63 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],63 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
64 "stateMutability": "nonpayable",64 "stateMutability": "nonpayable",
65 "type": "function"65 "type": "function"
modifiedtests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import * as solc from 'solc';
17import {expect} from 'chai';18import {expect} from 'chai';
18import {expectSubstrateEventsAtBlock} from '../util/helpers';19import {expectSubstrateEventsAtBlock} from '../util/helpers';
20import Web3 from 'web3';
21
19import {22import {
20 contractHelpers,23 contractHelpers,
26 createEthAccount,29 createEthAccount,
27 ethBalanceViaSub,30 ethBalanceViaSub,
28 normalizeEvents,31 normalizeEvents,
32 CompiledContract,
33 GAS_ARGS,
34 subToEth,
29} from './util/helpers';35} from './util/helpers';
36import {submitTransactionAsync} from '../substrate/substrate-api';
3037
31describe('Sponsoring EVM contracts', () => {38describe('Sponsoring EVM contracts', () => {
32 itWeb3('Self sponsored can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {39 itWeb3('Self sponsored can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {
479 });486 });
480});487});
488
489describe('Sponsoring Fee Limit', () => {
490
491 let testContract: CompiledContract;
492
493 function compileTestContract() {
494 if (!testContract) {
495 const input = {
496 language: 'Solidity',
497 sources: {
498 ['TestContract.sol']: {
499 content:
500 `
501 // SPDX-License-Identifier: MIT
502 pragma solidity ^0.8.0;
503
504 contract TestContract {
505 event Result(bool);
506
507 function test(uint32 cycles) public {
508 uint256 counter = 0;
509 while(true) {
510 counter ++;
511 if (counter > cycles){
512 break;
513 }
514 }
515 emit Result(true);
516 }
517 }
518 `,
519 },
520 },
521 settings: {
522 outputSelection: {
523 '*': {
524 '*': ['*'],
525 },
526 },
527 },
528 };
529 const json = JSON.parse(solc.compile(JSON.stringify(input)));
530 const out = json.contracts['TestContract.sol']['TestContract'];
531
532 testContract = {
533 abi: out.abi,
534 object: '0x' + out.evm.bytecode.object,
535 };
536 }
537 return testContract;
538 }
539
540 async function deployTestContract(web3: Web3, owner: string) {
541 const compiled = compileTestContract();
542 const testContract = new web3.eth.Contract(compiled.abi, undefined, {
543 data: compiled.object,
544 from: owner,
545 ...GAS_ARGS,
546 });
547 return await testContract.deploy({data: compiled.object}).send({from: owner});
548 }
549
550 itWeb3('Default fee limit', async ({api, web3, privateKeyWrapper}) => {
551 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
552 const flipper = await deployFlipper(web3, owner);
553 const helpers = contractHelpers(web3, owner);
554 expect(await helpers.methods.getSponsoringFeeLimit(flipper.options.address).call()).to.be.equals('115792089237316195423570985008687907853269984665640564039457584007913129639935');
555 });
556
557 itWeb3('Set fee limit', async ({api, web3, privateKeyWrapper}) => {
558 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
559 const flipper = await deployFlipper(web3, owner);
560 const helpers = contractHelpers(web3, owner);
561 await helpers.methods.setSponsoringFeeLimit(flipper.options.address, 100).send();
562 expect(await helpers.methods.getSponsoringFeeLimit(flipper.options.address).call()).to.be.equals('100');
563 });
564
565 itWeb3('Negative test - set fee limit by non-owner', async ({api, web3, privateKeyWrapper}) => {
566 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
567 const stranger = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
568 const flipper = await deployFlipper(web3, owner);
569 const helpers = contractHelpers(web3, owner);
570 await expect(helpers.methods.setSponsoringFeeLimit(flipper.options.address, 100).send({from: stranger})).to.be.rejected;
571 });
572
573 itWeb3('Negative test - check that eth transactions exceeding fee limit are not executed', async ({api, web3, privateKeyWrapper}) => {
574 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
575 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
576 const user = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
577
578 const testContract = await deployTestContract(web3, owner);
579 const helpers = contractHelpers(web3, owner);
580
581 await helpers.methods.setSponsoringMode(testContract.options.address, SponsoringMode.Generous).send({from: owner});
582 await helpers.methods.setSponsoringRateLimit(testContract.options.address, 0).send({from: owner});
583
584 await helpers.methods.setSponsor(testContract.options.address, sponsor).send();
585 await helpers.methods.confirmSponsorship(testContract.options.address).send({from: sponsor});
586
587 const gasPrice = BigInt(await web3.eth.getGasPrice());
588
589 await helpers.methods.setSponsoringFeeLimit(testContract.options.address, 2_000_000n * gasPrice).send();
590
591 const originalUserBalance = await web3.eth.getBalance(user);
592 await testContract.methods.test(100).send({from: user, gas: 2_000_000});
593 expect(await web3.eth.getBalance(user)).to.be.equal(originalUserBalance);
594
595 await testContract.methods.test(100).send({from: user, gas: 2_100_000});
596 expect(await web3.eth.getBalance(user)).to.not.be.equal(originalUserBalance);
597 });
598
599 itWeb3('Negative test - check that evm.call transactions exceeding fee limit are not executed', async ({api, web3, privateKeyWrapper}) => {
600 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
601 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
602
603 const testContract = await deployTestContract(web3, owner);
604 const helpers = contractHelpers(web3, owner);
605
606 await helpers.methods.setSponsoringMode(testContract.options.address, SponsoringMode.Generous).send({from: owner});
607 await helpers.methods.setSponsoringRateLimit(testContract.options.address, 0).send({from: owner});
608
609 await helpers.methods.setSponsor(testContract.options.address, sponsor).send();
610 await helpers.methods.confirmSponsorship(testContract.options.address).send({from: sponsor});
611
612 const gasPrice = BigInt(await web3.eth.getGasPrice());
613
614 await helpers.methods.setSponsoringFeeLimit(testContract.options.address, 2_000_000n * gasPrice).send();
615
616 const alice = privateKeyWrapper('//Alice');
617 const originalAliceBalance = (await api.query.system.account(alice.address)).data.free.toBigInt();
618
619 await submitTransactionAsync(
620 alice,
621 api.tx.evm.call(
622 subToEth(alice.address),
623 testContract.options.address,
624 testContract.methods.test(100).encodeABI(),
625 Uint8Array.from([]),
626 2_000_000n,
627 gasPrice,
628 null,
629 null,
630 [],
631 ),
632 );
633 expect((await api.query.system.account(alice.address)).data.free.toBigInt()).to.be.equal(originalAliceBalance);
634
635 await submitTransactionAsync(
636 alice,
637 api.tx.evm.call(
638 subToEth(alice.address),
639 testContract.options.address,
640 testContract.methods.test(100).encodeABI(),
641 Uint8Array.from([]),
642 2_100_000n,
643 gasPrice,
644 null,
645 null,
646 [],
647 ),
648 );
649 expect((await api.query.system.account(alice.address)).data.free.toBigInt()).to.not.be.equal(originalAliceBalance);
650 });
651});
481652
modifiedtests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth
41 41
42 const collectionCountBefore = await getCreatedCollectionCount(api);42 const collectionCountBefore = await getCreatedCollectionCount(api);
43 const result = await collectionHelper.methods43 const result = await collectionHelper.methods
44 .createRefungibleCollection(collectionName, description, tokenPrefix)44 .createRFTCollection(collectionName, description, tokenPrefix)
45 .send();45 .send();
46 const collectionCountAfter = await getCreatedCollectionCount(api);46 const collectionCountAfter = await getCreatedCollectionCount(api);
47 47
65 .call()).to.be.false;65 .call()).to.be.false;
6666
67 await collectionHelpers.methods67 await collectionHelpers.methods
68 .createRefungibleCollection('A', 'A', 'A')68 .createRFTCollection('A', 'A', 'A')
69 .send();69 .send();
70 70
71 expect(await collectionHelpers.methods71 expect(await collectionHelpers.methods
76 itWeb3('Set sponsorship', async ({api, web3, privateKeyWrapper}) => {76 itWeb3('Set sponsorship', async ({api, web3, privateKeyWrapper}) => {
77 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);77 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
78 const collectionHelpers = evmCollectionHelpers(web3, owner);78 const collectionHelpers = evmCollectionHelpers(web3, owner);
79 let result = await collectionHelpers.methods.createRefungibleCollection('Sponsor collection', '1', '1').send();79 let result = await collectionHelpers.methods.createRFTCollection('Sponsor collection', '1', '1').send();
80 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);80 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
81 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);81 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
82 const collectionEvm = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});82 const collectionEvm = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
96 itWeb3('Set limits', async ({api, web3, privateKeyWrapper}) => {96 itWeb3('Set limits', async ({api, web3, privateKeyWrapper}) => {
97 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);97 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
98 const collectionHelpers = evmCollectionHelpers(web3, owner);98 const collectionHelpers = evmCollectionHelpers(web3, owner);
99 const result = await collectionHelpers.methods.createRefungibleCollection('Const collection', '5', '5').send();99 const result = await collectionHelpers.methods.createRFTCollection('Const collection', '5', '5').send();
100 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);100 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
101 const limits = {101 const limits = {
102 accountTokenOwnershipLimit: 1000,102 accountTokenOwnershipLimit: 1000,
141 .isCollectionExist(collectionAddressForNonexistentCollection).call())141 .isCollectionExist(collectionAddressForNonexistentCollection).call())
142 .to.be.false;142 .to.be.false;
143 143
144 const result = await collectionHelpers.methods.createRefungibleCollection('Collection address exist', '7', '7').send();144 const result = await collectionHelpers.methods.createRFTCollection('Collection address exist', '7', '7').send();
145 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);145 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
146 expect(await collectionHelpers.methods146 expect(await collectionHelpers.methods
147 .isCollectionExist(collectionIdAddress).call())147 .isCollectionExist(collectionIdAddress).call())
164 const tokenPrefix = 'A';164 const tokenPrefix = 'A';
165 165
166 await expect(helper.methods166 await expect(helper.methods
167 .createRefungibleCollection(collectionName, description, tokenPrefix)167 .createRFTCollection(collectionName, description, tokenPrefix)
168 .call()).to.be.rejectedWith('name is too long. Max length is ' + MAX_NAME_LENGHT);168 .call()).to.be.rejectedWith('name is too long. Max length is ' + MAX_NAME_LENGHT);
169 169
170 }170 }
174 const description = 'A'.repeat(MAX_DESCRIPTION_LENGHT + 1);174 const description = 'A'.repeat(MAX_DESCRIPTION_LENGHT + 1);
175 const tokenPrefix = 'A';175 const tokenPrefix = 'A';
176 await expect(helper.methods176 await expect(helper.methods
177 .createRefungibleCollection(collectionName, description, tokenPrefix)177 .createRFTCollection(collectionName, description, tokenPrefix)
178 .call()).to.be.rejectedWith('description is too long. Max length is ' + MAX_DESCRIPTION_LENGHT);178 .call()).to.be.rejectedWith('description is too long. Max length is ' + MAX_DESCRIPTION_LENGHT);
179 }179 }
180 { 180 {
183 const description = 'A';183 const description = 'A';
184 const tokenPrefix = 'A'.repeat(MAX_TOKEN_PREFIX_LENGHT + 1);184 const tokenPrefix = 'A'.repeat(MAX_TOKEN_PREFIX_LENGHT + 1);
185 await expect(helper.methods185 await expect(helper.methods
186 .createRefungibleCollection(collectionName, description, tokenPrefix)186 .createRFTCollection(collectionName, description, tokenPrefix)
187 .call()).to.be.rejectedWith('token_prefix is too long. Max length is ' + MAX_TOKEN_PREFIX_LENGHT);187 .call()).to.be.rejectedWith('token_prefix is too long. Max length is ' + MAX_TOKEN_PREFIX_LENGHT);
188 }188 }
189 });189 });
196 const tokenPrefix = 'A';196 const tokenPrefix = 'A';
197 197
198 await expect(helper.methods198 await expect(helper.methods
199 .createRefungibleCollection(collectionName, description, tokenPrefix)199 .createRFTCollection(collectionName, description, tokenPrefix)
200 .call()).to.be.rejectedWith('NotSufficientFounds');200 .call()).to.be.rejectedWith('NotSufficientFounds');
201 });201 });
202202
203 itWeb3('(!negative test!) Check owner', async ({api, web3, privateKeyWrapper}) => {203 itWeb3('(!negative test!) Check owner', async ({api, web3, privateKeyWrapper}) => {
204 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);204 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
205 const notOwner = createEthAccount(web3);205 const notOwner = createEthAccount(web3);
206 const collectionHelpers = evmCollectionHelpers(web3, owner);206 const collectionHelpers = evmCollectionHelpers(web3, owner);
207 const result = await collectionHelpers.methods.createRefungibleCollection('A', 'A', 'A').send();207 const result = await collectionHelpers.methods.createRFTCollection('A', 'A', 'A').send();
208 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);208 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
209 const contractEvmFromNotOwner = evmCollection(web3, notOwner, collectionIdAddress, {type: 'ReFungible'});209 const contractEvmFromNotOwner = evmCollection(web3, notOwner, collectionIdAddress, {type: 'ReFungible'});
210 const EXPECTED_ERROR = 'NoPermission';210 const EXPECTED_ERROR = 'NoPermission';
229 itWeb3('(!negative test!) Set limits', async ({api, web3, privateKeyWrapper}) => {229 itWeb3('(!negative test!) Set limits', async ({api, web3, privateKeyWrapper}) => {
230 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);230 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
231 const collectionHelpers = evmCollectionHelpers(web3, owner);231 const collectionHelpers = evmCollectionHelpers(web3, owner);
232 const result = await collectionHelpers.methods.createRefungibleCollection('Schema collection', 'A', 'A').send();232 const result = await collectionHelpers.methods.createRFTCollection('Schema collection', 'A', 'A').send();
233 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);233 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
234 const collectionEvm = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});234 const collectionEvm = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
235 await expect(collectionEvm.methods235 await expect(collectionEvm.methods
modifiedtests/src/eth/fractionalizer/Fractionalizer.soldiffbeforeafterboth
84 "RFT collection is already set"
85 );
86 address collectionHelpers = 0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F;84 address collectionHelpers = 0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F;
87 rftCollection = CollectionHelpers(collectionHelpers).createRefungibleCollection(_name, _description, _tokenPrefix);85 rftCollection = CollectionHelpers(collectionHelpers).createRFTCollection(_name, _description, _tokenPrefix);
88 emit RFTCollectionSet(rftCollection);86 emit RFTCollectionSet(rftCollection);
89 }87 }
9088
modifiedtests/src/eth/fractionalizer/fractionalizer.test.tsdiffbeforeafterboth
21import {readFile} from 'fs/promises';21import {readFile} from 'fs/promises';
22import {executeTransaction, submitTransactionAsync} from '../../substrate/substrate-api';22import {executeTransaction, submitTransactionAsync} from '../../substrate/substrate-api';
23import {getCreateCollectionResult, getCreateItemResult, UNIQUE, requirePallets, Pallets} from '../../util/helpers';23import {getCreateCollectionResult, getCreateItemResult, UNIQUE, requirePallets, Pallets} from '../../util/helpers';
24import {collectionIdToAddress, CompiledContract, createEthAccountWithBalance, createNonfungibleCollection, createRefungibleCollection, GAS_ARGS, itWeb3, tokenIdFromAddress, uniqueNFT, uniqueRefungible, uniqueRefungibleToken} from '../util/helpers';24import {collectionIdToAddress, CompiledContract, createEthAccountWithBalance, createNonfungibleCollection, createRFTCollection, GAS_ARGS, itWeb3, tokenIdFromAddress, uniqueNFT, uniqueRefungible, uniqueRefungibleToken} from '../util/helpers';
25import {Contract} from 'web3-eth-contract';25import {Contract} from 'web3-eth-contract';
26import * as solc from 'solc';26import * as solc from 'solc';
2727
123 itWeb3('Set RFT collection', async ({api, web3, privateKeyWrapper}) => {123 itWeb3('Set RFT collection', async ({api, web3, privateKeyWrapper}) => {
124 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);124 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
125 const fractionalizer = await deployFractionalizer(web3, owner);125 const fractionalizer = await deployFractionalizer(web3, owner);
126 const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner);126 const {collectionIdAddress} = await createRFTCollection(api, web3, owner);
127 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);127 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
128 await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send();128 await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send();
129 const result = await fractionalizer.methods.setRFTCollection(collectionIdAddress).send();129 const result = await fractionalizer.methods.setRFTCollection(collectionIdAddress).send();
256256
257 itWeb3('call setRFTCollection twice', async ({api, web3, privateKeyWrapper}) => {257 itWeb3('call setRFTCollection twice', async ({api, web3, privateKeyWrapper}) => {
258 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);258 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
259 const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner);259 const {collectionIdAddress} = await createRFTCollection(api, web3, owner);
260 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);260 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
261261
262 const fractionalizer = await deployFractionalizer(web3, owner);262 const fractionalizer = await deployFractionalizer(web3, owner);
282 itWeb3('call setRFTCollection while not collection admin', async ({api, web3, privateKeyWrapper}) => {282 itWeb3('call setRFTCollection while not collection admin', async ({api, web3, privateKeyWrapper}) => {
283 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);283 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
284 const fractionalizer = await deployFractionalizer(web3, owner);284 const fractionalizer = await deployFractionalizer(web3, owner);
285 const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner);285 const {collectionIdAddress} = await createRFTCollection(api, web3, owner);
286286
287 await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())287 await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())
288 .to.be.rejectedWith(/Fractionalizer contract should be an admin of the collection$/g);288 .to.be.rejectedWith(/Fractionalizer contract should be an admin of the collection$/g);
368 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);368 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
369369
370 const fractionalizer = await deployFractionalizer(web3, owner);370 const fractionalizer = await deployFractionalizer(web3, owner);
371 const {collectionIdAddress: rftCollectionAddress} = await createRefungibleCollection(api, web3, owner);371 const {collectionIdAddress: rftCollectionAddress} = await createRFTCollection(api, web3, owner);
372 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);372 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
373 const rftTokenId = await refungibleContract.methods.nextTokenId().call();373 const rftTokenId = await refungibleContract.methods.nextTokenId().call();
374 await refungibleContract.methods.mint(owner, rftTokenId).send();374 await refungibleContract.methods.mint(owner, rftTokenId).send();
381 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);381 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
382382
383 const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);383 const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
384 const {collectionIdAddress: rftCollectionAddress} = await createRefungibleCollection(api, web3, owner);384 const {collectionIdAddress: rftCollectionAddress} = await createRFTCollection(api, web3, owner);
385 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);385 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
386 const rftTokenId = await refungibleContract.methods.nextTokenId().call();386 const rftTokenId = await refungibleContract.methods.nextTokenId().call();
387 await refungibleContract.methods.mint(owner, rftTokenId).send();387 await refungibleContract.methods.mint(owner, rftTokenId).send();
392392
393 itWeb3('call rft2nft for RFT token that was not minted by fractionalizer contract', async ({api, web3, privateKeyWrapper}) => {393 itWeb3('call rft2nft for RFT token that was not minted by fractionalizer contract', async ({api, web3, privateKeyWrapper}) => {
394 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);394 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
395 const {collectionIdAddress: rftCollectionAddress} = await createRefungibleCollection(api, web3, owner);395 const {collectionIdAddress: rftCollectionAddress} = await createRFTCollection(api, web3, owner);
396396
397 const fractionalizer = await deployFractionalizer(web3, owner);397 const fractionalizer = await deployFractionalizer(web3, owner);
398 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);398 const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
modifiedtests/src/eth/fungibleAbi.jsondiffbeforeafterboth
76 "stateMutability": "nonpayable",76 "stateMutability": "nonpayable",
77 "type": "function"77 "type": "function"
78 },78 },
79 {
80 "inputs": [
81 { "internalType": "uint256", "name": "user", "type": "uint256" }
82 ],
83 "name": "addToCollectionAllowListSubstrate",
84 "outputs": [],
85 "stateMutability": "nonpayable",
86 "type": "function"
87 },
79 {88 {
80 "inputs": [89 "inputs": [
81 { "internalType": "address", "name": "owner", "type": "address" },90 { "internalType": "address", "name": "owner", "type": "address" },
86 "stateMutability": "view",95 "stateMutability": "view",
87 "type": "function"96 "type": "function"
88 },97 },
98 {
99 "inputs": [
100 { "internalType": "address", "name": "user", "type": "address" }
101 ],
102 "name": "allowed",
103 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
104 "stateMutability": "view",
105 "type": "function"
106 },
89 {107 {
90 "inputs": [108 "inputs": [
91 { "internalType": "address", "name": "spender", "type": "address" },109 { "internalType": "address", "name": "spender", "type": "address" },
115 "stateMutability": "nonpayable",133 "stateMutability": "nonpayable",
116 "type": "function"134 "type": "function"
117 },135 },
136 {
137 "inputs": [],
138 "name": "collectionOwner",
139 "outputs": [
140 {
141 "components": [
142 { "internalType": "address", "name": "field_0", "type": "address" },
143 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
144 ],
145 "internalType": "struct Tuple6",
146 "name": "",
147 "type": "tuple"
148 }
149 ],
150 "stateMutability": "view",
151 "type": "function"
152 },
118 {153 {
119 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],154 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
120 "name": "collectionProperty",155 "name": "collectionProperty",
260 "stateMutability": "nonpayable",295 "stateMutability": "nonpayable",
261 "type": "function"296 "type": "function"
262 },297 },
298 {
299 "inputs": [
300 { "internalType": "uint256", "name": "user", "type": "uint256" }
301 ],
302 "name": "removeFromCollectionAllowListSubstrate",
303 "outputs": [],
304 "stateMutability": "nonpayable",
305 "type": "function"
306 },
263 {307 {
264 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],308 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],
265 "name": "setCollectionAccess",309 "name": "setCollectionAccess",
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
107 "stateMutability": "nonpayable",107 "stateMutability": "nonpayable",
108 "type": "function"108 "type": "function"
109 },109 },
110 {
111 "inputs": [
112 { "internalType": "uint256", "name": "user", "type": "uint256" }
113 ],
114 "name": "addToCollectionAllowListSubstrate",
115 "outputs": [],
116 "stateMutability": "nonpayable",
117 "type": "function"
118 },
119 {
120 "inputs": [
121 { "internalType": "address", "name": "user", "type": "address" }
122 ],
123 "name": "allowed",
124 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
125 "stateMutability": "view",
126 "type": "function"
127 },
110 {128 {
111 "inputs": [129 "inputs": [
112 { "internalType": "address", "name": "approved", "type": "address" },130 { "internalType": "address", "name": "approved", "type": "address" },
145 "stateMutability": "nonpayable",163 "stateMutability": "nonpayable",
146 "type": "function"164 "type": "function"
147 },165 },
166 {
167 "inputs": [],
168 "name": "collectionOwner",
169 "outputs": [
170 {
171 "components": [
172 { "internalType": "address", "name": "field_0", "type": "address" },
173 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
174 ],
175 "internalType": "struct Tuple17",
176 "name": "",
177 "type": "tuple"
178 }
179 ],
180 "stateMutability": "view",
181 "type": "function"
182 },
148 {183 {
149 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],184 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
150 "name": "collectionProperty",185 "name": "collectionProperty",
374 "stateMutability": "nonpayable",409 "stateMutability": "nonpayable",
375 "type": "function"410 "type": "function"
376 },411 },
412 {
413 "inputs": [
414 { "internalType": "uint256", "name": "user", "type": "uint256" }
415 ],
416 "name": "removeFromCollectionAllowListSubstrate",
417 "outputs": [],
418 "stateMutability": "nonpayable",
419 "type": "function"
420 },
377 {421 {
378 "inputs": [422 "inputs": [
379 { "internalType": "address", "name": "from", "type": "address" },423 { "internalType": "address", "name": "from", "type": "address" },
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
26 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {26 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {
27 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);27 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
28 const helper = evmCollectionHelpers(web3, caller);28 const helper = evmCollectionHelpers(web3, caller);
29 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();29 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
30 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);30 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
31 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});31 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
32 const nextTokenId = await contract.methods.nextTokenId().call();32 const nextTokenId = await contract.methods.nextTokenId().call();
38 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {38 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {
39 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);39 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
40 const helper = evmCollectionHelpers(web3, caller);40 const helper = evmCollectionHelpers(web3, caller);
41 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();41 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
42 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);42 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
43 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});43 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
4444
63 itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {63 itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {
64 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);64 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
65 const helper = evmCollectionHelpers(web3, caller);65 const helper = evmCollectionHelpers(web3, caller);
66 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();66 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
67 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);67 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
68 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});68 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
6969
79 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);79 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
80 const receiver = createEthAccount(web3);80 const receiver = createEthAccount(web3);
81 const helper = evmCollectionHelpers(web3, caller);81 const helper = evmCollectionHelpers(web3, caller);
82 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();82 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
83 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);83 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
84 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});84 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
8585
103 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);103 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
104 const receiver = createEthAccount(web3);104 const receiver = createEthAccount(web3);
105 const helper = evmCollectionHelpers(web3, caller);105 const helper = evmCollectionHelpers(web3, caller);
106 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();106 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
107 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);107 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
108 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});108 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
109109
130 itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {130 itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
131 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);131 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
132 const helper = evmCollectionHelpers(web3, owner);132 const helper = evmCollectionHelpers(web3, owner);
133 let result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();133 let result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
134 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);134 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
135 const receiver = createEthAccount(web3);135 const receiver = createEthAccount(web3);
136 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});136 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
163 itWeb3('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {163 itWeb3('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {
164 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);164 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
165 const helper = evmCollectionHelpers(web3, caller);165 const helper = evmCollectionHelpers(web3, caller);
166 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();166 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
167 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);167 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
168 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});168 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
169169
221 itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {221 itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {
222 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);222 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
223 const helper = evmCollectionHelpers(web3, caller);223 const helper = evmCollectionHelpers(web3, caller);
224 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();224 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
225 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);225 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
226 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});226 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
227227
247 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {247 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {
248 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);248 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
249 const helper = evmCollectionHelpers(web3, caller);249 const helper = evmCollectionHelpers(web3, caller);
250 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();250 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
251 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);251 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
252 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});252 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
253253
304 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {304 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {
305 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);305 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
306 const helper = evmCollectionHelpers(web3, caller);306 const helper = evmCollectionHelpers(web3, caller);
307 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();307 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
308 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);308 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
309 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});309 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
310310
344 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);344 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
345 const receiver = createEthAccount(web3);345 const receiver = createEthAccount(web3);
346 const helper = evmCollectionHelpers(web3, caller);346 const helper = evmCollectionHelpers(web3, caller);
347 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();347 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
348 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);348 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
349 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});349 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
350350
376 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);376 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
377 const receiver = createEthAccount(web3);377 const receiver = createEthAccount(web3);
378 const helper = evmCollectionHelpers(web3, caller);378 const helper = evmCollectionHelpers(web3, caller);
379 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();379 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
380 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);380 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
381 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});381 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
382382
413 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {413 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
414 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);414 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
415 const helper = evmCollectionHelpers(web3, caller);415 const helper = evmCollectionHelpers(web3, caller);
416 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();416 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
417 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);417 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
418 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});418 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
419419
430 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {430 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
431 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);431 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
432 const helper = evmCollectionHelpers(web3, caller);432 const helper = evmCollectionHelpers(web3, caller);
433 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();433 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
434 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);434 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
435 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});435 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
436436
modifiedtests/src/eth/reFungibleAbi.jsondiffbeforeafterboth
107 "stateMutability": "nonpayable",107 "stateMutability": "nonpayable",
108 "type": "function"108 "type": "function"
109 },109 },
110 {
111 "inputs": [
112 { "internalType": "uint256", "name": "user", "type": "uint256" }
113 ],
114 "name": "addToCollectionAllowListSubstrate",
115 "outputs": [],
116 "stateMutability": "nonpayable",
117 "type": "function"
118 },
119 {
120 "inputs": [
121 { "internalType": "address", "name": "user", "type": "address" }
122 ],
123 "name": "allowed",
124 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
125 "stateMutability": "view",
126 "type": "function"
127 },
110 {128 {
111 "inputs": [129 "inputs": [
112 { "internalType": "address", "name": "approved", "type": "address" },130 { "internalType": "address", "name": "approved", "type": "address" },
145 "stateMutability": "nonpayable",163 "stateMutability": "nonpayable",
146 "type": "function"164 "type": "function"
147 },165 },
166 {
167 "inputs": [],
168 "name": "collectionOwner",
169 "outputs": [
170 {
171 "components": [
172 { "internalType": "address", "name": "field_0", "type": "address" },
173 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
174 ],
175 "internalType": "struct Tuple17",
176 "name": "",
177 "type": "tuple"
178 }
179 ],
180 "stateMutability": "view",
181 "type": "function"
182 },
148 {183 {
149 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],184 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
150 "name": "collectionProperty",185 "name": "collectionProperty",
374 "stateMutability": "nonpayable",409 "stateMutability": "nonpayable",
375 "type": "function"410 "type": "function"
376 },411 },
412 {
413 "inputs": [
414 { "internalType": "uint256", "name": "user", "type": "uint256" }
415 ],
416 "name": "removeFromCollectionAllowListSubstrate",
417 "outputs": [],
418 "stateMutability": "nonpayable",
419 "type": "function"
420 },
377 {421 {
378 "inputs": [422 "inputs": [
379 { "internalType": "address", "name": "from", "type": "address" },423 { "internalType": "address", "name": "from", "type": "address" },
modifiedtests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE, requirePallets, Pallets} from '../util/helpers';17import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE, requirePallets, Pallets} from '../util/helpers';
18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, createRefungibleCollection, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth, uniqueRefungible, uniqueRefungibleToken} from './util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, createRFTCollection, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth, uniqueRefungible, uniqueRefungibleToken} from './util/helpers';
1919
20import chai from 'chai';20import chai from 'chai';
21import chaiAsPromised from 'chai-as-promised';21import chaiAsPromised from 'chai-as-promised';
458 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);458 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
459 const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);459 const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
460 const helper = evmCollectionHelpers(web3, caller);460 const helper = evmCollectionHelpers(web3, caller);
461 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();461 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
462 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);462 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
463 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});463 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
464464
658 itWeb3('Default parent token address and id', async ({api, web3, privateKeyWrapper}) => {658 itWeb3('Default parent token address and id', async ({api, web3, privateKeyWrapper}) => {
659 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);659 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
660660
661 const {collectionIdAddress, collectionId} = await createRefungibleCollection(api, web3, owner);661 const {collectionIdAddress, collectionId} = await createRFTCollection(api, web3, owner);
662 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);662 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
663 const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();663 const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();
664 await refungibleContract.methods.mint(owner, refungibleTokenId).send();664 await refungibleContract.methods.mint(owner, refungibleTokenId).send();
modifiedtests/src/eth/util/contractHelpersAbi.jsondiffbeforeafterboth
126 "stateMutability": "view",126 "stateMutability": "view",
127 "type": "function"127 "type": "function"
128 },128 },
129 {
130 "inputs": [
131 {
132 "internalType": "address",
133 "name": "contractAddress",
134 "type": "address"
135 }
136 ],
137 "name": "getSponsoringFeeLimit",
138 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
139 "stateMutability": "view",
140 "type": "function"
141 },
129 {142 {
130 "inputs": [143 "inputs": [
131 {144 {
205 "stateMutability": "nonpayable",218 "stateMutability": "nonpayable",
206 "type": "function"219 "type": "function"
207 },220 },
221 {
222 "inputs": [
223 {
224 "internalType": "address",
225 "name": "contractAddress",
226 "type": "address"
227 },
228 { "internalType": "uint256", "name": "feeLimit", "type": "uint256" }
229 ],
230 "name": "setSponsoringFeeLimit",
231 "outputs": [],
232 "stateMutability": "nonpayable",
233 "type": "function"
234 },
208 {235 {
209 "inputs": [236 "inputs": [
210 {237 {
modifiedtests/src/eth/util/helpers.tsdiffbeforeafterboth
141 expect(result.success).to.be.true;141 expect(result.success).to.be.true;
142}142}
143143
144export async function createRefungibleCollection(api: ApiPromise, web3: Web3, owner: string) {144export async function createRFTCollection(api: ApiPromise, web3: Web3, owner: string) {
145 const collectionHelper = evmCollectionHelpers(web3, owner);145 const collectionHelper = evmCollectionHelpers(web3, owner);
146 const result = await collectionHelper.methods146 const result = await collectionHelper.methods
147 .createRefungibleCollection('A', 'B', 'C')147 .createRFTCollection('A', 'B', 'C')
148 .send();148 .send();
149 return await getCollectionAddressFromResult(api, result);149 return await getCollectionAddressFromResult(api, result);
150}150}
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
1677 });1677 });
1678}1678}
16791679
1680export async function isAllowlisted(api: ApiPromise, collectionId: number, address: string | CrossAccountId) {1680export async function isAllowlisted(api: ApiPromise, collectionId: number, address: string | CrossAccountId | IKeyringPair) {
1681 return (await api.rpc.unique.allowed(collectionId, normalizeAccountId(address))).toJSON();1681 return (await api.rpc.unique.allowed(collectionId, normalizeAccountId(address))).toJSON();
1682}1682}
16831683
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
729 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved');729 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved');
730 }730 }
731
732 /**
733 * Check if user is in allow list.
734 *
735 * @param collectionId ID of collection
736 * @param user Account to check
737 * @example await getAdmins(1)
738 * @returns is user in allow list
739 */
740 async allowed(collectionId: number, user: ICrossAccountId): Promise<boolean> {
741 return (await this.helper.callRpc('api.rpc.unique.allowed', [collectionId, user])).toJSON();
742 }
731743
732 /**744 /**
733 * Adds an address to allow list745 * Adds an address to allow list