difftreelog
Merge branch 'develop' into tests/generalization
in: master
41 files changed
.docker/Dockerfile-chain-devdiffbeforeafterboth1FROM ubuntu:20.041FROM uniquenetwork/services:latest223ARG RUST_TOOLCHAIN3ARG RUST_TOOLCHAIN4ARG NETWORK4ARG NETWORK111112RUN echo "$NETWORK\n" && echo "$RUST_TOOLCHAIN\n"12RUN echo "$NETWORK\n" && echo "$RUST_TOOLCHAIN\n"131314RUN apt-get update && apt-get install -y git curl libssl-dev llvm pkg-config libclang-dev clang git make cmake protobuf-compiler1516RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none1718RUN rustup toolchain uninstall $(rustup toolchain list) && \14RUN rustup toolchain uninstall $(rustup toolchain list) && \19 rustup toolchain install $RUST_TOOLCHAIN && \15 rustup toolchain install $RUST_TOOLCHAIN && \20 rustup default $RUST_TOOLCHAIN && \16 rustup default $RUST_TOOLCHAIN && \.docker/Dockerfile-chain-dev-unitdiffbeforeafterboth1FROM ubuntu:20.041FROM uniquenetwork/services:latest223ENV DEBIAN_FRONTEND=noninteractive3ENV DEBIAN_FRONTEND=noninteractive4ENV TZ=Etc/UTC56RUN apt-get update && apt-get install -y git curl libssl-dev llvm pkg-config libclang-dev clang git make cmake protobuf-compiler78ENV CARGO_HOME="/cargo-home"4ENV CARGO_HOME="/cargo-home"9ENV PATH="/cargo-home/bin:$PATH"5ENV PATH="/cargo-home/bin:$PATH"1011RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none12613ARG RUST_TOOLCHAIN7ARG RUST_TOOLCHAIN14ARG NETWORK8ARG NETWORK.docker/Dockerfile-parachaindiffbeforeafterboth2FROM uniquenetwork/builder-polkadot:${POLKADOT_BUILD_BRANCH} as polkadot2FROM uniquenetwork/builder-polkadot:${POLKADOT_BUILD_BRANCH} as polkadot334# ===== Rust builder =====4# ===== Rust builder =====5FROM ubuntu:20.04 as rust-builder5FROM uniquenetwork/services:latest as rust-builder6LABEL maintainer="Unique.Network"78ARG RUST_TOOLCHAIN=6ARG RUST_TOOLCHAIN=9ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN7ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN10811ENV CARGO_HOME="/cargo-home"9ENV CARGO_HOME="/cargo-home"12ENV PATH="/cargo-home/bin:$PATH"10ENV PATH="/cargo-home/bin:$PATH"13ENV TZ=UTC11ENV TZ=UTC14RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone1516RUN apt-get update && \17 apt-get install -y curl cmake pkg-config libssl-dev git clang protobuf-compiler && \18 apt-get clean && \19 rm -r /var/lib/apt/lists/*2021RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none2223RUN rustup toolchain uninstall $(rustup toolchain list) && \12RUN rustup toolchain uninstall $(rustup toolchain list) && \24 rustup toolchain install $RUST_TOOLCHAIN && \13 rustup toolchain install $RUST_TOOLCHAIN && \25 rustup default $RUST_TOOLCHAIN && \14 rustup default $RUST_TOOLCHAIN && \.docker/Dockerfile-parachain-node-onlydiffbeforeafterboth2FROM uniquenetwork/builder-polkadot:${POLKADOT_BUILD_BRANCH} as polkadot2FROM uniquenetwork/builder-polkadot:${POLKADOT_BUILD_BRANCH} as polkadot334# ===== Rust builder =====4# ===== Rust builder =====5FROM ubuntu:20.04 as rust-builder5FROM uniquenetwork/services:latest as rust-builder6LABEL maintainer="Unique.Network"768ARG RUST_TOOLCHAIN=7ARG RUST_TOOLCHAIN=910ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN8ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN11ENV CARGO_HOME="/cargo-home"9ENV CARGO_HOME="/cargo-home"12ENV PATH="/cargo-home/bin:$PATH"10ENV PATH="/cargo-home/bin:$PATH"13ENV TZ=UTC11ENV TZ=UTC14RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone1516RUN apt-get update && \17 apt-get install -y curl cmake pkg-config libssl-dev git clang protobuf-compiler && \18 apt-get clean && \19 rm -r /var/lib/apt/lists/*2021RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none2223RUN rustup toolchain uninstall $(rustup toolchain list) && \12RUN rustup toolchain uninstall $(rustup toolchain list) && \24 rustup toolchain install $RUST_TOOLCHAIN && \13 rustup toolchain install $RUST_TOOLCHAIN && \25 rustup default $RUST_TOOLCHAIN && \14 rustup default $RUST_TOOLCHAIN && \.docker/Dockerfile-parachain-upgradediffbeforeafterboth2FROM uniquenetwork/builder-polkadot:${POLKADOT_BUILD_BRANCH} as polkadot2FROM uniquenetwork/builder-polkadot:${POLKADOT_BUILD_BRANCH} as polkadot334# ===== Rust builder =====4# ===== Rust builder =====5FROM ubuntu:20.04 as rust-builder5FROM uniquenetwork/services:latest as rust-builder6LABEL maintainer="Unique.Network"768ARG RUST_TOOLCHAIN=7ARG RUST_TOOLCHAIN=9810ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN9ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN11ENV CARGO_HOME="/cargo-home"10ENV CARGO_HOME="/cargo-home"12ENV PATH="/cargo-home/bin:$PATH"11ENV PATH="/cargo-home/bin:$PATH"13ENV TZ=UTC12ENV TZ=UTC14RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone1516RUN apt-get update && \17 apt-get install -y curl cmake pkg-config libssl-dev git clang protobuf-compiler && \18 apt-get clean && \19 rm -r /var/lib/apt/lists/*2021RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none2223RUN rustup toolchain uninstall $(rustup toolchain list) && \13RUN rustup toolchain uninstall $(rustup toolchain list) && \24 rustup toolchain install $RUST_TOOLCHAIN && \14 rustup toolchain install $RUST_TOOLCHAIN && \25 rustup default $RUST_TOOLCHAIN && \15 rustup default $RUST_TOOLCHAIN && \.docker/Dockerfile-parachain-upgrade-datadiffbeforeafterboth2FROM uniquenetwork/builder-polkadot:${POLKADOT_BUILD_BRANCH} as polkadot2FROM uniquenetwork/builder-polkadot:${POLKADOT_BUILD_BRANCH} as polkadot334# ===== Rust builder =====4# ===== Rust builder =====5FROM ubuntu:20.04 as rust-builder5FROM uniquenetwork/services:latest as rust-builder6LABEL maintainer="Unique.Network"78ARG RUST_TOOLCHAIN=6ARG RUST_TOOLCHAIN=9710ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN8ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN11ENV CARGO_HOME="/cargo-home"9ENV CARGO_HOME="/cargo-home"12ENV PATH="/cargo-home/bin:$PATH"10ENV PATH="/cargo-home/bin:$PATH"13ENV TZ=UTC11ENV TZ=UTC14RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone1516RUN apt-get update && \17 apt-get install -y curl cmake pkg-config libssl-dev git clang protobuf-compiler && \18 apt-get clean && \19 rm -r /var/lib/apt/lists/*2021RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none221223RUN rustup toolchain uninstall $(rustup toolchain list) && \13RUN rustup toolchain uninstall $(rustup toolchain list) && \24 rustup toolchain install $RUST_TOOLCHAIN && \14 rustup toolchain install $RUST_TOOLCHAIN && \.docker/Dockerfile-testnet.j2diffbeforeafterboth1# ===== Rust builder =====1# ===== Rust builder =====2FROM ubuntu:20.04 as rust-builder2FROM uniquenetwork/services:latest as rust-builder3LABEL maintainer="Unique.Network"3ARG RUST_TOOLCHAIN=445ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN5ENV CARGO_HOME="/cargo-home"6ENV CARGO_HOME="/cargo-home"6ENV PATH="/cargo-home/bin:$PATH"7ENV PATH="/cargo-home/bin:$PATH"7ENV TZ=UTC8ENV TZ=UTC8RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone9910RUN apt-get update && \11 apt-get install -y curl cmake pkg-config libssl-dev git clang llvm libudev-dev protobuf-compiler && \12 apt-get clean && \13 rm -r /var/lib/apt/lists/*1415RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none1617RUN rustup toolchain uninstall $(rustup toolchain list) && \10RUN rustup toolchain uninstall $(rustup toolchain list) && \18 rustup toolchain install {{ RUST_TOOLCHAIN }} && \11 rustup toolchain install {{ RUST_TOOLCHAIN }} && \19 rustup default {{ RUST_TOOLCHAIN }} && \12 rustup default {{ RUST_TOOLCHAIN }} && \.docker/Dockerfile-try-runtimediffbeforeafterboth1# ===== Rust builder =====1# ===== Rust builder =====2FROM ubuntu:20.04 as rust-builder2FROM uniquenetwork/services:latest as rust-builder3LABEL maintainer="Unique.Network"435ARG RUST_TOOLCHAIN4ARG RUST_TOOLCHAIN657ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN6ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN8ENV CARGO_HOME="/cargo-home"7ENV CARGO_HOME="/cargo-home"9ENV PATH="/cargo-home/bin:$PATH"8ENV PATH="/cargo-home/bin:$PATH"10ENV TZ=UTC9ENV TZ=UTC11RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone12101314RUN apt-get update && \15 apt-get install -y curl cmake pkg-config libssl-dev git clang protobuf-compiler && \16 apt-get clean && \17 rm -r /var/lib/apt/lists/*1819RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none2021RUN rustup toolchain uninstall $(rustup toolchain list) && \11RUN rustup toolchain uninstall $(rustup toolchain list) && \22 rustup toolchain install $RUST_TOOLCHAIN && \12 rustup toolchain install $RUST_TOOLCHAIN && \23 rustup default $RUST_TOOLCHAIN && \13 rustup default $RUST_TOOLCHAIN && \.docker/Dockerfile-xcm.j2diffbeforeafterboth1# ===== Rust builder =====1# ===== Rust builder =====2FROM ubuntu:20.04 as rust-builder2FROM uniquenetwork/services:latest as rust-builder3LABEL maintainer="Unique.Network"45ENV CARGO_HOME="/cargo-home"3ENV CARGO_HOME="/cargo-home"6ENV PATH="/cargo-home/bin:$PATH"4ENV PATH="/cargo-home/bin:$PATH"7ENV TZ=UTC5ENV TZ=UTC8RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone910RUN apt-get update && \11 apt-get install -y curl cmake pkg-config libssl-dev git clang llvm libudev-dev protobuf-compiler && \12 apt-get clean && \13 rm -r /var/lib/apt/lists/*1415RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none16617RUN rustup toolchain uninstall $(rustup toolchain list) && \7RUN rustup toolchain uninstall $(rustup toolchain list) && \18 rustup toolchain install {{ RUST_TOOLCHAIN }} && \8 rustup toolchain install {{ RUST_TOOLCHAIN }} && \Cargo.lockdiffbeforeafterboth234023402341[[package]]2341[[package]]2342name = "evm-coder-procedural"2342name = "evm-coder-procedural"2343version = "0.2.2"2343version = "0.2.3"2344dependencies = [2344dependencies = [2345 "Inflector",2345 "Inflector",2346 "hex",2346 "hex",2467[[package]]2467[[package]]2468name = "fc-consensus"2468name = "fc-consensus"2469version = "2.0.0-dev"2469version = "2.0.0-dev"2470source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2470source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2471dependencies = [2471dependencies = [2472 "async-trait",2472 "async-trait",2473 "fc-db",2473 "fc-db",2486[[package]]2486[[package]]2487name = "fc-db"2487name = "fc-db"2488version = "2.0.0-dev"2488version = "2.0.0-dev"2489source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2489source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2490dependencies = [2490dependencies = [2491 "fp-storage",2491 "fp-storage",2492 "kvdb-rocksdb",2492 "kvdb-rocksdb",2505[[package]]2505[[package]]2506name = "fc-mapping-sync"2506name = "fc-mapping-sync"2507version = "2.0.0-dev"2507version = "2.0.0-dev"2508source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2508source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2509dependencies = [2509dependencies = [2510 "fc-db",2510 "fc-db",2511 "fp-consensus",2511 "fp-consensus",2522[[package]]2522[[package]]2523name = "fc-rpc"2523name = "fc-rpc"2524version = "2.0.0-dev"2524version = "2.0.0-dev"2525source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2525source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2526dependencies = [2526dependencies = [2527 "ethereum 0.14.0",2527 "ethereum 0.14.0",2528 "ethereum-types 0.14.1",2528 "ethereum-types 0.14.1",2565[[package]]2565[[package]]2566name = "fc-rpc-core"2566name = "fc-rpc-core"2567version = "1.1.0-dev"2567version = "1.1.0-dev"2568source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2568source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2569dependencies = [2569dependencies = [2570 "ethereum 0.14.0",2570 "ethereum 0.14.0",2571 "ethereum-types 0.14.1",2571 "ethereum-types 0.14.1",2730[[package]]2730[[package]]2731name = "fp-consensus"2731name = "fp-consensus"2732version = "2.0.0-dev"2732version = "2.0.0-dev"2733source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2733source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2734dependencies = [2734dependencies = [2735 "ethereum 0.14.0",2735 "ethereum 0.14.0",2736 "parity-scale-codec 3.2.1",2736 "parity-scale-codec 3.2.1",2742[[package]]2742[[package]]2743name = "fp-ethereum"2743name = "fp-ethereum"2744version = "1.0.0-dev"2744version = "1.0.0-dev"2745source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2745source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2746dependencies = [2746dependencies = [2747 "ethereum 0.14.0",2747 "ethereum 0.14.0",2748 "ethereum-types 0.14.1",2748 "ethereum-types 0.14.1",2757[[package]]2757[[package]]2758name = "fp-evm"2758name = "fp-evm"2759version = "3.0.0-dev"2759version = "3.0.0-dev"2760source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2760source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2761dependencies = [2761dependencies = [2762 "evm",2762 "evm",2763 "frame-support",2763 "frame-support",2771[[package]]2771[[package]]2772name = "fp-evm-mapping"2772name = "fp-evm-mapping"2773version = "0.1.0"2773version = "0.1.0"2774source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2774source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2775dependencies = [2775dependencies = [2776 "frame-support",2776 "frame-support",2777 "sp-core",2777 "sp-core",2780[[package]]2780[[package]]2781name = "fp-rpc"2781name = "fp-rpc"2782version = "3.0.0-dev"2782version = "3.0.0-dev"2783source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2783source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2784dependencies = [2784dependencies = [2785 "ethereum 0.14.0",2785 "ethereum 0.14.0",2786 "ethereum-types 0.14.1",2786 "ethereum-types 0.14.1",2797[[package]]2797[[package]]2798name = "fp-self-contained"2798name = "fp-self-contained"2799version = "1.0.0-dev"2799version = "1.0.0-dev"2800source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2800source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2801dependencies = [2801dependencies = [2802 "ethereum 0.14.0",2802 "ethereum 0.14.0",2803 "frame-support",2803 "frame-support",2810[[package]]2810[[package]]2811name = "fp-storage"2811name = "fp-storage"2812version = "2.0.0"2812version = "2.0.0"2813source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"2813source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"2814dependencies = [2814dependencies = [2815 "parity-scale-codec 3.2.1",2815 "parity-scale-codec 3.2.1",2816 "serde",2816 "serde",5687[[package]]5687[[package]]5688name = "pallet-base-fee"5688name = "pallet-base-fee"5689version = "1.0.0"5689version = "1.0.0"5690source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"5690source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"5691dependencies = [5691dependencies = [5692 "fp-evm",5692 "fp-evm",5693 "frame-support",5693 "frame-support",5952[[package]]5952[[package]]5953name = "pallet-ethereum"5953name = "pallet-ethereum"5954version = "4.0.0-dev"5954version = "4.0.0-dev"5955source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"5955source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"5956dependencies = [5956dependencies = [5957 "ethereum 0.14.0",5957 "ethereum 0.14.0",5958 "ethereum-types 0.14.1",5958 "ethereum-types 0.14.1",5980[[package]]5980[[package]]5981name = "pallet-evm"5981name = "pallet-evm"5982version = "6.0.0-dev"5982version = "6.0.0-dev"5983source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"5983source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"5984dependencies = [5984dependencies = [5985 "environmental",5985 "environmental",5986 "evm",5986 "evm",6066[[package]]6066[[package]]6067name = "pallet-evm-precompile-simple"6067name = "pallet-evm-precompile-simple"6068version = "2.0.0-dev"6068version = "2.0.0-dev"6069source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"6069source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#ef8d2809ed05da0664e9b43cb87436451295b634"6070dependencies = [6070dependencies = [6071 "fp-evm",6071 "fp-evm",6072 "ripemd",6072 "ripemd",crates/evm-coder/procedural/Cargo.tomldiffbeforeafterboth1[package]1[package]2name = "evm-coder-procedural"2name = "evm-coder-procedural"3version = "0.2.2"3version = "0.2.3"4license = "GPLv3"4license = "GPLv3"5edition = "2021"5edition = "2021"66crates/evm-coder/procedural/src/solidity_interface.rsdiffbeforeafterboth811 let list = generics_list(gen);811 let list = generics_list(gen);812 quote! { <#list> }812 quote! { <#list> }813}813}814fn generics_stub(gen: &Generics) -> proc_macro2::TokenStream {815 if gen.params.is_empty() {816 return quote! {};817 }818 let params = (0..gen.params.len()).map(|_| quote! {()});819 quote! {<#(#params,)*>}820}814fn generics_data(gen: &Generics) -> proc_macro2::TokenStream {821fn generics_data(gen: &Generics) -> proc_macro2::TokenStream {815 let list = generics_list(gen);822 let list = generics_list(gen);816 if gen.params.len() == 1 {823 if gen.params.len() == 1 {866 let generics = self.generics;873 let generics = self.generics;867 let gen_ref = generics_reference(&generics);874 let gen_ref = generics_reference(&generics);868 let gen_data = generics_data(&generics);875 let gen_data = generics_data(&generics);876 let gen_stub = generics_stub(&generics);869 let gen_where = &generics.where_clause;877 let gen_where = &generics.where_clause;870878871 let call_sub = self879 let call_sub = self936 let solidity_events_idents = self.info.events.0.iter().map(|is| is.name.clone());944 let solidity_events_idents = self.info.events.0.iter().map(|is| is.name.clone());937 let docs = &self.docs;945 let docs = &self.docs;946947 let expect_selector = self.info.expect_selector.map(|s| {948 quote! {949 const _: () = assert!(#s == u32::from_be_bytes(<#call_name #gen_stub>::interface_id()), "selector mismatch, review contained function selectors");950 }951 });938952939 quote! {953 quote! {940 #(954 #(953 )*967 )*954 }968 }969970 #expect_selector971955 impl #gen_ref #call_name #gen_ref {972 impl #gen_ref #call_name #gen_ref {956 #(973 #(957 #consts974 #consts958 )*975 )*959 /// Return this call ERC165 selector976 /// Return this call ERC165 selector960 pub fn interface_id() -> ::evm_coder::types::bytes4 {977 pub const fn interface_id() -> ::evm_coder::types::bytes4 {961 let mut interface_id = 0;978 let mut interface_id = 0;962 #(#interface_id)*979 #(#interface_id)*963 #(#inline_interface_id)*980 #(#inline_interface_id)*crates/evm-coder/procedural/src/to_log.rsdiffbeforeafterboth161617use inflector::cases;17use inflector::cases;18use syn::{Data, DeriveInput, Field, Fields, Ident, Variant, spanned::Spanned};18use syn::{Data, DeriveInput, Field, Fields, Ident, Variant, spanned::Spanned};19use std::fmt::Write;20use quote::quote;19use quote::quote;212022use crate::{parse_ident_from_path, parse_ident_from_type, snake_ident_to_screaming};21use crate::{parse_ident_from_path, parse_ident_from_type, snake_ident_to_screaming};61 name: Ident,60 name: Ident,62 name_screaming: Ident,61 name_screaming: Ident,63 fields: Vec<EventField>,62 fields: Vec<EventField>,64 selector: [u8; 32],63 selector: proc_macro2::TokenStream,65 selector_str: String,66}64}676568impl Event {66impl Event {69 fn try_from(variant: &Variant) -> syn::Result<Self> {67 fn try_from(variant: &Variant) -> syn::Result<Self> {70 let name = &variant.ident;68 let name = &variant.ident;69 let name_lit = proc_macro2::Literal::string(name.to_string().as_str());71 let name_screaming = snake_ident_to_screaming(name);70 let name_screaming = snake_ident_to_screaming(name);727173 let named = match &variant.fields {72 let named = match &variant.fields {90 ));89 ));91 }90 }9192 let mut selector_str = format!("{}(", name);92 let args = fields.iter().map(|f| {93 let ty = &f.ty;94 quote! {nameof(<#ty as ::evm_coder::abi::AbiType>::SIGNATURE) fixed(",")}93 for (i, arg) in fields.iter().enumerate() {95 });94 if i != 0 {96 // Remove trailing comma95 write!(selector_str, ",").unwrap();96 }97 write!(selector_str, "{}", arg.ty).unwrap();97 let shift = (!fields.is_empty()).then(|| quote! {shift_left(1)});98 }9899 selector_str.push(')');99 let signature = quote! { ::evm_coder::make_signature!(new fixed(#name_lit) fixed("(") #(#args)* #shift fixed(")")) };100 let selector = crate::event_selector_str(&selector_str);100 let selector = quote! {101 {102 let signature = #signature;103 let mut sum = ::evm_coder::sha3_const::Keccak256::new();104 let mut pos = 0;105 while pos < signature.len {106 sum = sum.update(&[signature.data[pos]; 1]);107 pos += 1;108 }109 let a = sum.finalize();110 let mut selector_bytes = [0; 32];111 let mut i = 0;112 while i != 32 {113 selector_bytes[i] = a[i];114 i += 1;115 }116 selector_bytes117 }118 };101119102 Ok(Self {120 Ok(Self {103 name: name.to_owned(),121 name: name.to_owned(),104 name_screaming,122 name_screaming,105 fields,123 fields,106 selector,124 selector,107 selector_str,108 })125 })109 }126 }110127133150134 fn expand_consts(&self) -> proc_macro2::TokenStream {151 fn expand_consts(&self) -> proc_macro2::TokenStream {135 let name_screaming = &self.name_screaming;152 let name_screaming = &self.name_screaming;136 let selector_str = &self.selector_str;137 let selector = &self.selector;153 let selector = &self.selector;138154139 quote! {155 quote! {140 #[doc = #selector_str]141 const #name_screaming: [u8; 32] = [#(156 const #name_screaming: [u8; 32] = #selector;142 #selector,143 )*];144 }157 }145 }158 }146159node/cli/src/chain_spec.rsdiffbeforeafterboth143 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()143 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()144}144}145145146#[cfg(feature = "quartz-runtime")]146#[cfg(not(feature = "unique-runtime"))]147macro_rules! testnet_genesis {147macro_rules! testnet_genesis {148 (148 (149 $runtime:path,149 $runtime:path,207 }};207 }};208}208}209209210#[cfg(not(feature = "quartz-runtime"))]210#[cfg(feature = "unique-runtime")]211macro_rules! testnet_genesis {211macro_rules! testnet_genesis {212 (212 (213 $runtime:path,213 $runtime:path,pallets/common/src/benchmarking.rsdiffbeforeafterboth176 key: property_key(p as usize),176 key: property_key(p as usize),177 value: property_value(),177 value: property_value(),178 }).collect::<Vec<_>>();178 }).collect::<Vec<_>>();179 }: {<Pallet<T>>::set_collection_properties(&collection, &owner, props)?}179 }: {<Pallet<T>>::set_collection_properties(&collection, &owner, props.into_iter())?}180180181 delete_collection_properties {181 delete_collection_properties {182 let b in 0..MAX_PROPERTIES_PER_ITEM;182 let b in 0..MAX_PROPERTIES_PER_ITEM;188 key: property_key(p as usize),188 key: property_key(p as usize),189 value: property_value(),189 value: property_value(),190 }).collect::<Vec<_>>();190 }).collect::<Vec<_>>();191 <Pallet<T>>::set_collection_properties(&collection, &owner, props)?;191 <Pallet<T>>::set_collection_properties(&collection, &owner, props.into_iter())?;192 let to_delete = (0..b).map(|p| property_key(p as usize)).collect::<Vec<_>>();192 let to_delete = (0..b).map(|p| property_key(p as usize)).collect::<Vec<_>>();193 }: {<Pallet<T>>::delete_collection_properties(&collection, &owner, to_delete)?}193 }: {<Pallet<T>>::delete_collection_properties(&collection, &owner, to_delete.into_iter())?}194}194}195195pallets/common/src/erc.rsdiffbeforeafterboth125 .map(eth::Property::try_into)125 .map(eth::Property::try_into)126 .collect::<Result<Vec<_>>>()?;126 .collect::<Result<Vec<_>>>()?;127127128 <Pallet<T>>::set_collection_properties(self, &caller, properties)128 <Pallet<T>>::set_collection_properties(self, &caller, properties.into_iter())129 .map_err(dispatch_to_evm::<T>)129 .map_err(dispatch_to_evm::<T>)130 }130 }131131158 })158 })159 .collect::<Result<Vec<_>>>()?;159 .collect::<Result<Vec<_>>>()?;160160161 <Pallet<T>>::delete_collection_properties(self, &caller, keys).map_err(dispatch_to_evm::<T>)161 <Pallet<T>>::delete_collection_properties(self, &caller, keys.into_iter())162 .map_err(dispatch_to_evm::<T>)162 }163 }163164pallets/common/src/lib.rsdiffbeforeafterboth390 Ok(())390 Ok(())391 }391 }392392393 /// Return **true** if `user` was not allowed to have tokens, and he can ignore such restrictions.393 /// Returns **true** if394 /// * the `user`is a collection owner or admin395 /// * the collection limits allow the owner/admins to transfer/burn any collection token394 pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> bool {396 pub fn ignores_token_restrictions(&self, user: &T::CrossAccountId) -> bool {395 self.limits.owner_can_transfer() && self.is_owner_or_admin(user)397 self.limits.owner_can_transfer() && self.is_owner_or_admin(user)396 }398 }3973991198 Ok(())1200 Ok(())1199 }1201 }120012021201 /// Set collection property.1203 /// This function sets or removes a collection properties according to1204 /// `properties_updates` contents:1205 /// * sets a property under the <key> with the value provided `(<key>, Some(<value>))`1206 /// * removes a property under the <key> if the value is `None` `(<key>, None)`.1202 ///1207 ///1203 /// * `collection` - Collection handler.1208 /// This function fires an event for each property change.1204 /// * `sender` - The owner or administrator of the collection.1209 /// In case of an error, all the changes (including the events) will be reverted1205 /// * `property` - The property to set.1210 /// since the function is transactional.1211 #[transactional]1206 pub fn set_collection_property(1212 fn modify_collection_properties(1207 collection: &CollectionHandle<T>,1213 collection: &CollectionHandle<T>,1208 sender: &T::CrossAccountId,1214 sender: &T::CrossAccountId,1209 property: Property,1215 properties_updates: impl Iterator<Item = (PropertyKey, Option<PropertyValue>)>,1210 ) -> DispatchResult {1216 ) -> DispatchResult {1211 collection.check_is_owner_or_admin(sender)?;1217 collection.check_is_owner_or_admin(sender)?;121212181213 CollectionProperties::<T>::try_mutate(collection.id, |properties| {1219 let mut stored_properties = <CollectionProperties<T>>::get(collection.id);1214 let property = property.clone();12201215 properties.try_set(property.key, property.value)1221 for (key, value) in properties_updates {1216 })1222 match value {1217 .map_err(<Error<T>>::from)?;1223 Some(value) => {12181224 stored_properties1225 .try_set(key.clone(), value)1219 Self::deposit_event(Event::CollectionPropertySet(collection.id, property.key));1226 .map_err(<Error<T>>::from)?;12271228 Self::deposit_event(Event::CollectionPropertySet(collection.id, key));1220 <PalletEvm<T>>::deposit_log(1229 <PalletEvm<T>>::deposit_log(1221 erc::CollectionHelpersEvents::CollectionChanged {1230 erc::CollectionHelpersEvents::CollectionChanged {1222 collection_id: eth::collection_id_to_address(collection.id),1231 collection_id: eth::collection_id_to_address(collection.id),1223 }1232 }1224 .to_log(T::ContractAddress::get()),1233 .to_log(T::ContractAddress::get()),1225 );1234 );1235 }1236 None => {1237 stored_properties.remove(&key).map_err(<Error<T>>::from)?;12381239 Self::deposit_event(Event::CollectionPropertyDeleted(collection.id, key));1240 <PalletEvm<T>>::deposit_log(1241 erc::CollectionHelpersEvents::CollectionChanged {1242 collection_id: eth::collection_id_to_address(collection.id),1243 }1244 .to_log(T::ContractAddress::get()),1245 );1246 }1247 }1248 }12491250 <CollectionProperties<T>>::set(collection.id, stored_properties);122612511227 Ok(())1252 Ok(())1228 }1253 }12541255 /// Set collection property.1256 ///1257 /// * `collection` - Collection handler.1258 /// * `sender` - The owner or administrator of the collection.1259 /// * `property` - The property to set.1260 pub fn set_collection_property(1261 collection: &CollectionHandle<T>,1262 sender: &T::CrossAccountId,1263 property: Property,1264 ) -> DispatchResult {1265 Self::set_collection_properties(collection, sender, [property].into_iter())1266 }122912671230 /// Set a scoped collection property, where the scope is a special prefix1268 /// Set a scoped collection property, where the scope is a special prefix1231 /// prohibiting a user access to change the property directly.1269 /// prohibiting a user access to change the property directly.1270 /// * `collection` - Collection handler.1308 /// * `collection` - Collection handler.1271 /// * `sender` - The owner or administrator of the collection.1309 /// * `sender` - The owner or administrator of the collection.1272 /// * `properties` - The properties to set.1310 /// * `properties` - The properties to set.1273 #[transactional]1274 pub fn set_collection_properties(1311 pub fn set_collection_properties(1275 collection: &CollectionHandle<T>,1312 collection: &CollectionHandle<T>,1276 sender: &T::CrossAccountId,1313 sender: &T::CrossAccountId,1277 properties: Vec<Property>,1314 properties: impl Iterator<Item = Property>,1278 ) -> DispatchResult {1315 ) -> DispatchResult {1279 for property in properties {1280 Self::set_collection_property(collection, sender, property)?;1316 Self::modify_collection_properties(1281 }1317 collection,12821318 sender,1283 Ok(())1319 properties.map(|property| (property.key, Some(property.value))),1320 )1284 }1321 }128513221293 sender: &T::CrossAccountId,1330 sender: &T::CrossAccountId,1294 property_key: PropertyKey,1331 property_key: PropertyKey,1295 ) -> DispatchResult {1332 ) -> DispatchResult {1296 collection.check_is_owner_or_admin(sender)?;12971298 CollectionProperties::<T>::try_mutate(collection.id, |properties| {1299 properties.remove(&property_key)1300 })1301 .map_err(<Error<T>>::from)?;13021303 Self::deposit_event(Event::CollectionPropertyDeleted(1304 collection.id,1305 property_key,1306 ));1307 <PalletEvm<T>>::deposit_log(1333 Self::delete_collection_properties(collection, sender, [property_key].into_iter())1308 erc::CollectionHelpersEvents::CollectionChanged {1309 collection_id: eth::collection_id_to_address(collection.id),1310 }1311 .to_log(T::ContractAddress::get()),1312 );13131314 Ok(())1315 }1334 }131613351317 /// Delete collection properties.1336 /// Delete collection properties.1318 ///1337 ///1319 /// * `collection` - Collection handler.1338 /// * `collection` - Collection handler.1320 /// * `sender` - The owner or administrator of the collection.1339 /// * `sender` - The owner or administrator of the collection.1321 /// * `properties` - The properties to delete.1340 /// * `properties` - The properties to delete.1322 #[transactional]1323 pub fn delete_collection_properties(1341 pub fn delete_collection_properties(1324 collection: &CollectionHandle<T>,1342 collection: &CollectionHandle<T>,1325 sender: &T::CrossAccountId,1343 sender: &T::CrossAccountId,1326 property_keys: Vec<PropertyKey>,1344 property_keys: impl Iterator<Item = PropertyKey>,1327 ) -> DispatchResult {1345 ) -> DispatchResult {1328 for key in property_keys {1329 Self::delete_collection_property(collection, sender, key)?;1346 Self::modify_collection_properties(collection, sender, property_keys.map(|key| (key, None)))1330 }13311332 Ok(())1333 }1347 }133413481335 /// Set collection propetry permission without any checks.1349 /// Set collection propetry permission without any checks.pallets/fungible/src/lib.rsdiffbeforeafterboth266 sender: &T::CrossAccountId,266 sender: &T::CrossAccountId,267 properties: Vec<Property>,267 properties: Vec<Property>,268 ) -> DispatchResult {268 ) -> DispatchResult {269 <PalletCommon<T>>::set_collection_properties(collection, sender, properties)269 <PalletCommon<T>>::set_collection_properties(collection, sender, properties.into_iter())270 }270 }271271272 /// Delete properties of the collection, associated with the provided keys.272 /// Delete properties of the collection, associated with the provided keys.278 <PalletCommon<T>>::delete_collection_properties(collection, sender, property_keys)278 <PalletCommon<T>>::delete_collection_properties(279 collection,280 sender,281 property_keys.into_iter(),282 )279 }283 }280284674 collection.check_allowlist(spender)?;678 collection.check_allowlist(spender)?;675 }679 }680681 if collection.ignores_token_restrictions(spender) {682 return Ok(Self::compute_allowance_decrease(683 collection, from, spender, amount,684 ));685 }686676 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {687 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {677 // TODO: should collection owner be allowed to perform this transfer?678 ensure!(688 ensure!(679 <PalletStructure<T>>::check_indirectly_owned(689 <PalletStructure<T>>::check_indirectly_owned(680 spender.clone(),690 spender.clone(),688 return Ok(None);698 return Ok(None);689 }699 }700690 let allowance = <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount);701 let allowance = Self::compute_allowance_decrease(collection, from, spender, amount);691 if allowance.is_none() {692 ensure!(702 ensure!(allowance.is_some(), <CommonError<T>>::ApprovedValueTooLow);693 collection.ignores_allowance(spender),694 <CommonError<T>>::ApprovedValueTooLow695 );696 }697703698 Ok(allowance)704 Ok(allowance)699 }705 }706707 /// Returns `Some(amount)` if the `spender` have allowance to spend this amount.708 /// Otherwise, it returns `None`.709 fn compute_allowance_decrease(710 collection: &FungibleHandle<T>,711 from: &T::CrossAccountId,712 spender: &T::CrossAccountId,713 amount: u128,714 ) -> Option<u128> {715 <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount)716 }700717701 /// Transfer fungible tokens from one account to another.718 /// Transfer fungible tokens from one account to another.702 /// Same as the [`transfer`][`Pallet::transfer`] but spender doesn't needs to be an owner of the token pieces.719 /// Same as the [`transfer`][`Pallet::transfer`] but spender doesn't needs to be an owner of the token pieces.pallets/nonfungible/src/erc.rsdiffbeforeafterboth525 Ok(<Pallet<T>>::allowance_for_all(self, &owner, &operator))525 Ok(<Pallet<T>>::allowance_for_all(self, &owner, &operator))526 }526 }527528 /// @notice Returns collection helper contract address529 fn collection_helper_address(&self) -> Result<address> {530 Ok(T::ContractAddress::get())531 }532}527}533528534/// @title ERC721 Token that can be irreversibly burned (destroyed).529/// @title ERC721 Token that can be irreversibly burned (destroyed).1059 Ok(token_id.into())1054 Ok(token_id.into())1060 }1055 }10561057 /// @notice Returns collection helper contract address1058 fn collection_helper_address(&self) -> Result<address> {1059 Ok(T::ContractAddress::get())1060 }1061}1061}106210621063#[solidity_interface(1063#[solidity_interface(pallets/nonfungible/src/lib.rsdiffbeforeafterboth577 })577 })578 }578 }579579580 /// Batch operation to add, edit or remove properties for the token580 /// A batch operation to add, edit or remove properties for a token.581 ///581 /// It sets or removes a token's properties according to582 /// All affected properties should have mutable permission and sender should have582 /// `properties_updates` contents:583 /// permission to edit those properties.583 /// * sets a property under the <key> with the value provided `(<key>, Some(<value>))`584 /// * removes a property under the <key> if the value is `None` `(<key>, None)`.584 ///585 ///585 /// - `nesting_budget`: Limit for searching parents in depth to check ownership.586 /// - `nesting_budget`: Limit for searching parents in-depth to check ownership.586 /// - `is_token_create`: Indicates that method is called during token initialization.587 /// - `is_token_create`: Indicates that method is called during token initialization.587 /// Allows to bypass ownership check.588 /// Allows to bypass ownership check.589 ///590 /// All affected properties should have `mutable` permission591 /// to be **deleted** or to be **set more than once**,592 /// and the sender should have permission to edit those properties.593 ///594 /// This function fires an event for each property change.595 /// In case of an error, all the changes (including the events) will be reverted596 /// since the function is transactional.588 #[transactional]597 #[transactional]589 fn modify_token_properties(598 fn modify_token_properties(590 collection: &NonfungibleHandle<T>,599 collection: &NonfungibleHandle<T>,591 sender: &T::CrossAccountId,600 sender: &T::CrossAccountId,592 token_id: TokenId,601 token_id: TokenId,593 properties: impl Iterator<Item = (PropertyKey, Option<PropertyValue>)>,602 properties_updates: impl Iterator<Item = (PropertyKey, Option<PropertyValue>)>,594 is_token_create: bool,603 is_token_create: bool,595 nesting_budget: &dyn Budget,604 nesting_budget: &dyn Budget,596 ) -> DispatchResult {605 ) -> DispatchResult {614 })623 })615 };624 };625626 let mut stored_properties = <TokenProperties<T>>::get((collection.id, token_id));627 let permissions = <PalletCommon<T>>::property_permissions(collection.id);616628617 for (key, value) in properties {629 for (key, value) in properties_updates {618 let permission = <PalletCommon<T>>::property_permissions(collection.id)630 let permission = permissions619 .get(&key)631 .get(&key)620 .cloned()632 .cloned()621 .unwrap_or_else(PropertyPermission::none);633 .unwrap_or_else(PropertyPermission::none);622634623 let is_property_exists = TokenProperties::<T>::get((collection.id, token_id))635 let is_property_exists = stored_properties.get(&key).is_some();624 .get(&key)625 .is_some();626636649659650 match value {660 match value {651 Some(value) => {661 Some(value) => {652 <TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {662 stored_properties653 properties.try_set(key.clone(), value)663 .try_set(key.clone(), value)654 })655 .map_err(<CommonError<T>>::from)?;664 .map_err(<CommonError<T>>::from)?;656665657 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertySet(666 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertySet(661 ));670 ));662 }671 }663 None => {672 None => {664 <TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {673 stored_properties665 properties.remove(&key)674 .remove(&key)666 })667 .map_err(<CommonError<T>>::from)?;675 .map_err(<CommonError<T>>::from)?;668676669 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertyDeleted(677 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertyDeleted(683 );691 );684 }692 }693694 <TokenProperties<T>>::set((collection.id, token_id), stored_properties);685695686 Ok(())696 Ok(())687 }697 }784 sender: &T::CrossAccountId,794 sender: &T::CrossAccountId,785 properties: Vec<Property>,795 properties: Vec<Property>,786 ) -> DispatchResult {796 ) -> DispatchResult {787 <PalletCommon<T>>::set_collection_properties(collection, sender, properties)797 <PalletCommon<T>>::set_collection_properties(collection, sender, properties.into_iter())788 }798 }789799790 /// Remove properties from the collection800 /// Remove properties from the collection796 <PalletCommon<T>>::delete_collection_properties(collection, sender, property_keys)806 <PalletCommon<T>>::delete_collection_properties(807 collection,808 sender,809 property_keys.into_iter(),810 )797 }811 }7988121232 collection.check_allowlist(spender)?;1246 collection.check_allowlist(spender)?;1233 }1247 }123412481235 if collection.limits.owner_can_transfer() && collection.is_owner_or_admin(spender) {1249 if collection.ignores_token_restrictions(spender) {1236 return Ok(());1250 return Ok(());1237 }1251 }123812521255 if <CollectionAllowance<T>>::get((collection.id, from, spender)) {1269 if <CollectionAllowance<T>>::get((collection.id, from, spender)) {1256 return Ok(());1270 return Ok(());1257 }1271 }1258 ensure!(12721259 collection.ignores_allowance(spender),1260 <CommonError<T>>::ApprovedValueTooLow1273 Err(<CommonError<T>>::ApprovedValueTooLow.into())1261 );1262 Ok(())1263 }1274 }126412751265 /// Transfer NFT token from one account to another.1276 /// Transfer NFT token from one account to another.pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth785}785}786786787/// @title Unique extensions for ERC721.787/// @title Unique extensions for ERC721.788/// @dev the ERC-165 identifier for this interface is 0x0e48fdb4788/// @dev the ERC-165 identifier for this interface is 0x16de3152789contract ERC721UniqueExtensions is Dummy, ERC165 {789contract ERC721UniqueExtensions is Dummy, ERC165 {790 /// @notice A descriptive name for a collection of NFTs in this contract790 /// @notice A descriptive name for a collection of NFTs in this contract791 /// @dev EVM selector for this function is: 0x06fdde03,791 /// @dev EVM selector for this function is: 0x06fdde03,987 return 0;987 return 0;988 }988 }989990 /// @notice Returns collection helper contract address991 /// @dev EVM selector for this function is: 0x1896cce6,992 /// or in textual repr: collectionHelperAddress()993 function collectionHelperAddress() public view returns (address) {994 require(false, stub_error);995 dummy;996 return 0x0000000000000000000000000000000000000000;997 }989}998}990999991/// @dev anonymous struct1000/// @dev anonymous struct104310521044/// @title ERC-721 Non-Fungible Token Standard1053/// @title ERC-721 Non-Fungible Token Standard1045/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md1054/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md1046/// @dev the ERC-165 identifier for this interface is 0x983a942b1055/// @dev the ERC-165 identifier for this interface is 0x80ac58cd1047contract ERC721 is Dummy, ERC165, ERC721Events {1056contract ERC721 is Dummy, ERC165, ERC721Events {1048 /// @notice Count all NFTs assigned to an owner1057 /// @notice Count all NFTs assigned to an owner1049 /// @dev NFTs assigned to the zero address are considered invalid, and this1058 /// @dev NFTs assigned to the zero address are considered invalid, and this1177 return false;1186 return false;1178 }1187 }11791180 /// @notice Returns collection helper contract address1181 /// @dev EVM selector for this function is: 0x1896cce6,1182 /// or in textual repr: collectionHelperAddress()1183 function collectionHelperAddress() public view returns (address) {1184 require(false, stub_error);1185 dummy;1186 return 0x0000000000000000000000000000000000000000;1187 }1188}1188}118911891190contract UniqueNFT is1190contract UniqueNFT ispallets/nonfungible/src/weights.rsdiffbeforeafterboth184 .saturating_add(T::DbWeight::get().reads(1 as u64))184 .saturating_add(T::DbWeight::get().reads(1 as u64))185 .saturating_add(T::DbWeight::get().writes(1 as u64))185 .saturating_add(T::DbWeight::get().writes(1 as u64))186 }186 }187 // Storage: Common CollectionPropertyPermissions (r:1 w:0)188 // Storage: Nonfungible TokenProperties (r:1 w:1)187 // Storage: Nonfungible TokenProperties (r:1 w:1)188 // Storage: Common CollectionPropertyPermissions (r:1 w:0)189 fn set_token_properties(b: u32, ) -> Weight {189 fn set_token_properties(b: u32, ) -> Weight {190 Weight::from_ref_time(4_361_000 as u64)190 Weight::from_ref_time(31_850_484 as u64)191 // Standard Error: 5_349_868191 // Standard Error: 9_618192 .saturating_add(Weight::from_ref_time(637_246_356 as u64).saturating_mul(b as u64))192 .saturating_add(Weight::from_ref_time(4_721_947 as u64).saturating_mul(b as u64))193 .saturating_add(T::DbWeight::get().reads(2 as u64))193 .saturating_add(T::DbWeight::get().reads(2 as u64))194 .saturating_add(T::DbWeight::get().writes(1 as u64))194 .saturating_add(T::DbWeight::get().writes(1 as u64))195 }195 }196 // Storage: Common CollectionPropertyPermissions (r:1 w:0)197 // Storage: Nonfungible TokenProperties (r:1 w:1)196 // Storage: Nonfungible TokenProperties (r:1 w:1)197 // Storage: Common CollectionPropertyPermissions (r:1 w:0)198 fn delete_token_properties(b: u32, ) -> Weight {198 fn delete_token_properties(b: u32, ) -> Weight {199 Weight::from_ref_time(4_489_000 as u64)199 Weight::from_ref_time(13_795_000 as u64)200 // Standard Error: 5_738_954200 // Standard Error: 28_239201 .saturating_add(Weight::from_ref_time(689_912_822 as u64).saturating_mul(b as u64))201 .saturating_add(Weight::from_ref_time(12_840_446 as u64).saturating_mul(b as u64))202 .saturating_add(T::DbWeight::get().reads(2 as u64))202 .saturating_add(T::DbWeight::get().reads(2 as u64))203 .saturating_add(T::DbWeight::get().writes(1 as u64))203 .saturating_add(T::DbWeight::get().writes(1 as u64))204 }204 }354 .saturating_add(RocksDbWeight::get().reads(1 as u64))354 .saturating_add(RocksDbWeight::get().reads(1 as u64))355 .saturating_add(RocksDbWeight::get().writes(1 as u64))355 .saturating_add(RocksDbWeight::get().writes(1 as u64))356 }356 }357 // Storage: Common CollectionPropertyPermissions (r:1 w:0)358 // Storage: Nonfungible TokenProperties (r:1 w:1)357 // Storage: Nonfungible TokenProperties (r:1 w:1)358 // Storage: Common CollectionPropertyPermissions (r:1 w:0)359 fn set_token_properties(b: u32, ) -> Weight {359 fn set_token_properties(b: u32, ) -> Weight {360 Weight::from_ref_time(4_361_000 as u64)360 Weight::from_ref_time(31_850_484 as u64)361 // Standard Error: 5_349_868361 // Standard Error: 9_618362 .saturating_add(Weight::from_ref_time(637_246_356 as u64).saturating_mul(b as u64))362 .saturating_add(Weight::from_ref_time(4_721_947 as u64).saturating_mul(b as u64))363 .saturating_add(RocksDbWeight::get().reads(2 as u64))363 .saturating_add(RocksDbWeight::get().reads(2 as u64))364 .saturating_add(RocksDbWeight::get().writes(1 as u64))364 .saturating_add(RocksDbWeight::get().writes(1 as u64))365 }365 }366 // Storage: Common CollectionPropertyPermissions (r:1 w:0)367 // Storage: Nonfungible TokenProperties (r:1 w:1)366 // Storage: Nonfungible TokenProperties (r:1 w:1)367 // Storage: Common CollectionPropertyPermissions (r:1 w:0)368 fn delete_token_properties(b: u32, ) -> Weight {368 fn delete_token_properties(b: u32, ) -> Weight {369 Weight::from_ref_time(4_489_000 as u64)369 Weight::from_ref_time(13_795_000 as u64)370 // Standard Error: 5_738_954370 // Standard Error: 28_239371 .saturating_add(Weight::from_ref_time(689_912_822 as u64).saturating_mul(b as u64))371 .saturating_add(Weight::from_ref_time(12_840_446 as u64).saturating_mul(b as u64))372 .saturating_add(RocksDbWeight::get().reads(2 as u64))372 .saturating_add(RocksDbWeight::get().reads(2 as u64))373 .saturating_add(RocksDbWeight::get().writes(1 as u64))373 .saturating_add(RocksDbWeight::get().writes(1 as u64))374 }374 }pallets/refungible/src/erc.rsdiffbeforeafterboth295 MintingFinished {},295 MintingFinished {},296}296}297297298/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension299/// @dev See https://eips.ethereum.org/EIPS/eip-721298#[solidity_interface(name = ERC721Metadata)]300#[solidity_interface(name = ERC721Metadata, expect_selector = 0x5b5e139f)]299impl<T: Config> RefungibleHandle<T>301impl<T: Config> RefungibleHandle<T>300where302where301 T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,303 T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,364366365/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension367/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension366/// @dev See https://eips.ethereum.org/EIPS/eip-721368/// @dev See https://eips.ethereum.org/EIPS/eip-721367#[solidity_interface(name = ERC721Enumerable)]369#[solidity_interface(name = ERC721Enumerable, expect_selector = 0x780e9d63)]368impl<T: Config> RefungibleHandle<T> {370impl<T: Config> RefungibleHandle<T> {369 /// @notice Enumerate valid RFTs371 /// @notice Enumerate valid RFTs370 /// @param index A counter less than `totalSupply()`372 /// @param index A counter less than `totalSupply()`391393392/// @title ERC-721 Non-Fungible Token Standard394/// @title ERC-721 Non-Fungible Token Standard393/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md395/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md394#[solidity_interface(name = ERC721, events(ERC721Events))]396#[solidity_interface(name = ERC721, events(ERC721Events), expect_selector = 0x80ac58cd)]395impl<T: Config> RefungibleHandle<T> {397impl<T: Config> RefungibleHandle<T> {396 /// @notice Count all RFTs assigned to an owner398 /// @notice Count all RFTs assigned to an owner397 /// @dev RFTs assigned to the zero address are considered invalid, and this399 /// @dev RFTs assigned to the zero address are considered invalid, and this422 }424 }423425424 /// @dev Not implemented426 /// @dev Not implemented427 #[solidity(rename_selector = "safeTransferFrom")]425 fn safe_transfer_from_with_data(428 fn safe_transfer_from_with_data(426 &mut self,429 &mut self,427 _from: address,430 _from: address,434 }437 }435438436 /// @dev Not implemented439 /// @dev Not implemented440 #[solidity(rename_selector = "safeTransferFrom")]437 fn safe_transfer_from(441 fn safe_transfer_from(438 &mut self,442 &mut self,439 _from: address,443 _from: address,518 Ok(<Pallet<T>>::allowance_for_all(self, &owner, &operator))522 Ok(<Pallet<T>>::allowance_for_all(self, &owner, &operator))519 }523 }520521 /// @notice Returns collection helper contract address522 fn collection_helper_address(&self) -> Result<address> {523 Ok(T::ContractAddress::get())524 }525}524}526525527/// Returns amount of pieces of `token` that `owner` have526/// Returns amount of pieces of `token` that `owner` have1117 ))1116 ))1118 }1117 }11181119 /// @notice Returns collection helper contract address1120 fn collection_helper_address(&self) -> Result<address> {1121 Ok(T::ContractAddress::get())1122 }1119}1123}112011241121#[solidity_interface(1125#[solidity_interface(pallets/refungible/src/lib.rsdiffbeforeafterboth515 Ok(())515 Ok(())516 }516 }517517518 /// A batch operation to add, edit or remove properties for a token.519 /// It sets or removes a token's properties according to520 /// `properties_updates` contents:521 /// * sets a property under the <key> with the value provided `(<key>, Some(<value>))`522 /// * removes a property under the <key> if the value is `None` `(<key>, None)`.523 ///524 /// - `nesting_budget`: Limit for searching parents in-depth to check ownership.525 /// - `is_token_create`: Indicates that method is called during token initialization.526 /// Allows to bypass ownership check.527 ///528 /// All affected properties should have `mutable` permission529 /// to be **deleted** or to be **set more than once**,530 /// and the sender should have permission to edit those properties.531 ///532 /// This function fires an event for each property change.533 /// In case of an error, all the changes (including the events) will be reverted534 /// since the function is transactional.518 #[transactional]535 #[transactional]519 fn modify_token_properties(536 fn modify_token_properties(520 collection: &RefungibleHandle<T>,537 collection: &RefungibleHandle<T>,521 sender: &T::CrossAccountId,538 sender: &T::CrossAccountId,522 token_id: TokenId,539 token_id: TokenId,523 properties: impl Iterator<Item = (PropertyKey, Option<PropertyValue>)>,540 properties_updates: impl Iterator<Item = (PropertyKey, Option<PropertyValue>)>,524 is_token_create: bool,541 is_token_create: bool,525 nesting_budget: &dyn Budget,542 nesting_budget: &dyn Budget,526 ) -> DispatchResult {543 ) -> DispatchResult {544 Ok(is_bundle_owner)561 Ok(is_bundle_owner)545 };562 };563564 let mut stored_properties = <TokenProperties<T>>::get((collection.id, token_id));565 let permissions = <PalletCommon<T>>::property_permissions(collection.id);546566547 for (key, value) in properties {567 for (key, value) in properties_updates {548 let permission = <PalletCommon<T>>::property_permissions(collection.id)568 let permission = permissions549 .get(&key)569 .get(&key)550 .cloned()570 .cloned()551 .unwrap_or_else(PropertyPermission::none);571 .unwrap_or_else(PropertyPermission::none);552572553 let is_property_exists = TokenProperties::<T>::get((collection.id, token_id))573 let is_property_exists = stored_properties.get(&key).is_some();554 .get(&key)555 .is_some();556574578596579 match value {597 match value {580 Some(value) => {598 Some(value) => {581 <TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {599 stored_properties582 properties.try_set(key.clone(), value)600 .try_set(key.clone(), value)583 })584 .map_err(<CommonError<T>>::from)?;601 .map_err(<CommonError<T>>::from)?;585602586 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertySet(603 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertySet(590 ));607 ));591 }608 }592 None => {609 None => {593 <TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {610 stored_properties594 properties.remove(&key)611 .remove(&key)595 })596 .map_err(<CommonError<T>>::from)?;612 .map_err(<CommonError<T>>::from)?;597613598 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertyDeleted(614 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertyDeleted(612 );628 );613 }629 }630631 <TokenProperties<T>>::set((collection.id, token_id), stored_properties);614632615 Ok(())633 Ok(())616 }634 }1160 collection.check_allowlist(spender)?;1178 collection.check_allowlist(spender)?;1161 }1179 }11801181 if collection.ignores_token_restrictions(spender) {1182 return Ok(Self::compute_allowance_decrease(1183 collection, token, from, &spender, amount,1184 ));1185 }11861162 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {1187 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {1163 // TODO: should collection owner be allowed to perform this transfer?1188 // TODO: should collection owner be allowed to perform this transfer?1174 return Ok(None);1199 return Ok(None);1175 }1200 }12011176 let allowance =1202 let allowance = Self::compute_allowance_decrease(collection, token, from, &spender, amount);1177 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);1203 if allowance.is_some() {1204 return Ok(allowance);1205 }117812061179 // Allowance (if any) would be reduced if spender is also wallet operator1207 // Allowance (if any) would be reduced if spender is also wallet operator1180 if <CollectionAllowance<T>>::get((collection.id, from, spender)) {1208 if <CollectionAllowance<T>>::get((collection.id, from, spender)) {1181 return Ok(allowance);1209 return Ok(allowance);1182 }1210 }118312111184 if allowance.is_none() {1185 ensure!(1186 collection.ignores_allowance(spender),1187 <CommonError<T>>::ApprovedValueTooLow1212 Err(<CommonError<T>>::ApprovedValueTooLow.into())1188 );1189 }1190 Ok(allowance)1191 }1213 }12141215 /// Returns `Some(amount)` if the `spender` have allowance to spend this amount.1216 /// Otherwise, it returns `None`.1217 fn compute_allowance_decrease(1218 collection: &RefungibleHandle<T>,1219 token: TokenId,1220 from: &T::CrossAccountId,1221 spender: &T::CrossAccountId,1222 amount: u128,1223 ) -> Option<u128> {1224 <Allowance<T>>::get((collection.id, token, from, spender)).checked_sub(amount)1225 }119212261193 /// Transfer RFT token pieces from one account to another.1227 /// Transfer RFT token pieces from one account to another.1194 ///1228 ///1353 sender: &T::CrossAccountId,1387 sender: &T::CrossAccountId,1354 properties: Vec<Property>,1388 properties: Vec<Property>,1355 ) -> DispatchResult {1389 ) -> DispatchResult {1356 <PalletCommon<T>>::set_collection_properties(collection, sender, properties)1390 <PalletCommon<T>>::set_collection_properties(collection, sender, properties.into_iter())1357 }1391 }135813921359 pub fn delete_collection_properties(1393 pub fn delete_collection_properties(1364 <PalletCommon<T>>::delete_collection_properties(collection, sender, property_keys)1398 <PalletCommon<T>>::delete_collection_properties(1399 collection,1400 sender,1401 property_keys.into_iter(),1402 )1365 }1403 }13661404pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth641 TransferEnabled641 TransferEnabled642}642}643643644/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension645/// @dev See https://eips.ethereum.org/EIPS/eip-721644/// @dev the ERC-165 identifier for this interface is 0x5b5e139f646/// @dev the ERC-165 identifier for this interface is 0x5b5e139f645contract ERC721Metadata is Dummy, ERC165 {647contract ERC721Metadata is Dummy, ERC165 {646 // /// @notice A descriptive name for a collection of NFTs in this contract648 // /// @notice A descriptive name for a collection of NFTs in this contract783}785}784786785/// @title Unique extensions for ERC721.787/// @title Unique extensions for ERC721.786/// @dev the ERC-165 identifier for this interface is 0xabf30dc2788/// @dev the ERC-165 identifier for this interface is 0xb365c124787contract ERC721UniqueExtensions is Dummy, ERC165 {789contract ERC721UniqueExtensions is Dummy, ERC165 {788 /// @notice A descriptive name for a collection of NFTs in this contract790 /// @notice A descriptive name for a collection of NFTs in this contract789 /// @dev EVM selector for this function is: 0x06fdde03,791 /// @dev EVM selector for this function is: 0x06fdde03,986 return 0x0000000000000000000000000000000000000000;988 return 0x0000000000000000000000000000000000000000;987 }989 }990991 /// @notice Returns collection helper contract address992 /// @dev EVM selector for this function is: 0x1896cce6,993 /// or in textual repr: collectionHelperAddress()994 function collectionHelperAddress() public view returns (address) {995 require(false, stub_error);996 dummy;997 return 0x0000000000000000000000000000000000000000;998 }988}999}9891000990/// @dev anonymous struct1001/// @dev anonymous struct104210531043/// @title ERC-721 Non-Fungible Token Standard1054/// @title ERC-721 Non-Fungible Token Standard1044/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md1055/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md1045/// @dev the ERC-165 identifier for this interface is 0x4016cd871056/// @dev the ERC-165 identifier for this interface is 0x80ac58cd1046contract ERC721 is Dummy, ERC165, ERC721Events {1057contract ERC721 is Dummy, ERC165, ERC721Events {1047 /// @notice Count all RFTs assigned to an owner1058 /// @notice Count all RFTs assigned to an owner1048 /// @dev RFTs assigned to the zero address are considered invalid, and this1059 /// @dev RFTs assigned to the zero address are considered invalid, and this1075 }1086 }107610871077 /// @dev Not implemented1088 /// @dev Not implemented1078 /// @dev EVM selector for this function is: 0x60a11672,1089 /// @dev EVM selector for this function is: 0xb88d4fde,1079 /// or in textual repr: safeTransferFromWithData(address,address,uint256,bytes)1090 /// or in textual repr: safeTransferFrom(address,address,uint256,bytes)1080 function safeTransferFromWithData(1091 function safeTransferFrom(1081 address from,1092 address from,1082 address to,1093 address to,1083 uint256 tokenId,1094 uint256 tokenId,1174 return false;1185 return false;1175 }1186 }11761177 /// @notice Returns collection helper contract address1178 /// @dev EVM selector for this function is: 0x1896cce6,1179 /// or in textual repr: collectionHelperAddress()1180 function collectionHelperAddress() public view returns (address) {1181 require(false, stub_error);1182 dummy;1183 return 0x0000000000000000000000000000000000000000;1184 }1185}1187}118611881187contract UniqueRefungible is1189contract UniqueRefungible ispallets/refungible/src/weights.rsdiffbeforeafterboth246 .saturating_add(T::DbWeight::get().reads(1 as u64))246 .saturating_add(T::DbWeight::get().reads(1 as u64))247 .saturating_add(T::DbWeight::get().writes(1 as u64))247 .saturating_add(T::DbWeight::get().writes(1 as u64))248 }248 }249 // Storage: Common CollectionPropertyPermissions (r:1 w:0)250 // Storage: Refungible TokenProperties (r:1 w:1)249 // Storage: Refungible TokenProperties (r:1 w:1)250 // Storage: Common CollectionPropertyPermissions (r:1 w:0)251 fn set_token_properties(b: u32, ) -> Weight {251 fn set_token_properties(b: u32, ) -> Weight {252 Weight::from_ref_time(4_578_000 as u64)252 Weight::from_ref_time(25_518_267 as u64)253 // Standard Error: 5_396_287253 // Standard Error: 20_451254 .saturating_add(Weight::from_ref_time(633_314_546 as u64).saturating_mul(b as u64))254 .saturating_add(Weight::from_ref_time(5_041_089 as u64).saturating_mul(b as u64))255 .saturating_add(T::DbWeight::get().reads(2 as u64))255 .saturating_add(T::DbWeight::get().reads(2 as u64))256 .saturating_add(T::DbWeight::get().writes(1 as u64))256 .saturating_add(T::DbWeight::get().writes(1 as u64))257 }257 }258 // Storage: Common CollectionPropertyPermissions (r:1 w:0)259 // Storage: Refungible TokenProperties (r:1 w:1)258 // Storage: Refungible TokenProperties (r:1 w:1)259 // Storage: Common CollectionPropertyPermissions (r:1 w:0)260 fn delete_token_properties(b: u32, ) -> Weight {260 fn delete_token_properties(b: u32, ) -> Weight {261 Weight::from_ref_time(4_583_000 as u64)261 Weight::from_ref_time(13_715_000 as u64)262 // Standard Error: 5_762_380262 // Standard Error: 28_323263 .saturating_add(Weight::from_ref_time(696_007_076 as u64).saturating_mul(b as u64))263 .saturating_add(Weight::from_ref_time(13_113_351 as u64).saturating_mul(b as u64))264 .saturating_add(T::DbWeight::get().reads(2 as u64))264 .saturating_add(T::DbWeight::get().reads(2 as u64))265 .saturating_add(T::DbWeight::get().writes(1 as u64))265 .saturating_add(T::DbWeight::get().writes(1 as u64))266 }266 }478 .saturating_add(RocksDbWeight::get().reads(1 as u64))478 .saturating_add(RocksDbWeight::get().reads(1 as u64))479 .saturating_add(RocksDbWeight::get().writes(1 as u64))479 .saturating_add(RocksDbWeight::get().writes(1 as u64))480 }480 }481 // Storage: Common CollectionPropertyPermissions (r:1 w:0)482 // Storage: Refungible TokenProperties (r:1 w:1)481 // Storage: Refungible TokenProperties (r:1 w:1)482 // Storage: Common CollectionPropertyPermissions (r:1 w:0)483 fn set_token_properties(b: u32, ) -> Weight {483 fn set_token_properties(b: u32, ) -> Weight {484 Weight::from_ref_time(4_578_000 as u64)484 Weight::from_ref_time(25_518_267 as u64)485 // Standard Error: 5_396_287485 // Standard Error: 20_451486 .saturating_add(Weight::from_ref_time(633_314_546 as u64).saturating_mul(b as u64))486 .saturating_add(Weight::from_ref_time(5_041_089 as u64).saturating_mul(b as u64))487 .saturating_add(RocksDbWeight::get().reads(2 as u64))487 .saturating_add(RocksDbWeight::get().reads(2 as u64))488 .saturating_add(RocksDbWeight::get().writes(1 as u64))488 .saturating_add(RocksDbWeight::get().writes(1 as u64))489 }489 }490 // Storage: Common CollectionPropertyPermissions (r:1 w:0)491 // Storage: Refungible TokenProperties (r:1 w:1)490 // Storage: Refungible TokenProperties (r:1 w:1)491 // Storage: Common CollectionPropertyPermissions (r:1 w:0)492 fn delete_token_properties(b: u32, ) -> Weight {492 fn delete_token_properties(b: u32, ) -> Weight {493 Weight::from_ref_time(4_583_000 as u64)493 Weight::from_ref_time(13_715_000 as u64)494 // Standard Error: 5_762_380494 // Standard Error: 28_323495 .saturating_add(Weight::from_ref_time(696_007_076 as u64).saturating_mul(b as u64))495 .saturating_add(Weight::from_ref_time(13_113_351 as u64).saturating_mul(b as u64))496 .saturating_add(RocksDbWeight::get().reads(2 as u64))496 .saturating_add(RocksDbWeight::get().reads(2 as u64))497 .saturating_add(RocksDbWeight::get().writes(1 as u64))497 .saturating_add(RocksDbWeight::get().writes(1 as u64))498 }498 }pallets/unique/src/eth/mod.rsdiffbeforeafterboth33};33};34use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};34use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};35use pallet_evm_coder_substrate::{dispatch_to_evm, SubstrateRecorder, WithRecorder};35use pallet_evm_coder_substrate::{dispatch_to_evm, SubstrateRecorder, WithRecorder};36use sp_std::vec;37use up_data_structs::{36use up_data_structs::{38 CollectionDescription, CollectionMode, CollectionName, CollectionTokenPrefix,37 CollectionDescription, CollectionMode, CollectionName, CollectionTokenPrefix,39 CreateCollectionData,38 CreateCollectionData,316 <PalletCommon<T>>::set_collection_properties(315 <PalletCommon<T>>::set_collection_properties(317 &collection,316 &collection,318 &caller,317 &caller,319 vec![up_data_structs::Property {318 [up_data_structs::Property {320 key: key::base_uri(),319 key: key::base_uri(),321 value: base_uri320 value: base_uri322 .into_bytes()321 .into_bytes()323 .try_into()322 .try_into()324 .map_err(|_| "base uri is too large")?,323 .map_err(|_| "base uri is too large")?,325 }],324 }]325 .into_iter(),326 )326 )327 .map_err(dispatch_to_evm::<T>)?;327 .map_err(dispatch_to_evm::<T>)?;328 }328 }runtime/common/ethereum/sponsoring/refungible.rsdiffbeforeafterboth140 | OwnerOf { .. }140 | OwnerOf { .. }141 | GetApproved { .. }141 | GetApproved { .. }142 | IsApprovedForAll { .. }142 | IsApprovedForAll { .. } => None,143 | CollectionHelperAddress => None,144143145 // Not sponsored144 // Not sponsored146 SafeTransferFromWithData { .. }145 SafeTransferFromWithData { .. }231 | Properties { .. }230 | Properties { .. }232 | NextTokenId231 | NextTokenId233 | TokenContractAddress { .. } => None,232 | TokenContractAddress { .. }233 | CollectionHelperAddress => None,234234235 // Not sponsored235 // Not sponsored236 BurnFrom { .. }236 BurnFrom { .. }runtime/common/identity.rsdiffbeforeafterboth24 transaction_validity::{TransactionValidity, ValidTransaction, TransactionValidityError},24 transaction_validity::{TransactionValidity, ValidTransaction, TransactionValidityError},25};25};2627#[cfg(feature = "collator-selection")]28use sp_runtime::transaction_validity::InvalidTransaction;262927#[derive(Debug, Encode, Decode, PartialEq, Eq, Clone, TypeInfo)]30#[derive(Debug, Encode, Decode, PartialEq, Eq, Clone, TypeInfo)]28pub struct DisableIdentityCalls;31pub struct DisableIdentityCalls;runtime/common/runtime_apis.rsdiffbeforeafterboth451 }451 }452452453 fn account_code_at(address: H160) -> Vec<u8> {453 fn account_code_at(address: H160) -> Vec<u8> {454 use pallet_evm::OnMethodCall;455 <Runtime as pallet_evm::Config>::OnMethodCall::get_code(&address)454 EVM::account_codes(address)456 .unwrap_or_else(|| EVM::account_codes(address))455 }457 }456458457 fn author() -> H160 {459 fn author() -> H160 {runtime/opal/Cargo.tomldiffbeforeafterboth193 'refungible',193 'refungible',194 'rmrk',194 'rmrk',195 'app-promotion',195 'app-promotion',196 'collator-selection',196 'foreign-assets',197 'foreign-assets',197 'pallet-test-utils',198 'pallet-test-utils',198]199]tests/src/eth/abi/nonFungible.jsondiffbeforeafterboth49 "name": "ApprovalForAll",49 "name": "ApprovalForAll",50 "type": "event"50 "type": "event"51 },51 },52 {53 "anonymous": false,54 "inputs": [],55 "name": "MintingFinished",56 "type": "event"57 },52 {58 {53 "anonymous": false,59 "anonymous": false,54 "inputs": [60 "inputs": [416 "stateMutability": "view",422 "stateMutability": "view",417 "type": "function"423 "type": "function"418 },424 },425 {426 "inputs": [],427 "name": "finishMinting",428 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],429 "stateMutability": "nonpayable",430 "type": "function"431 },419 {432 {420 "inputs": [433 "inputs": [421 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }434 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }502 "stateMutability": "nonpayable",515 "stateMutability": "nonpayable",503 "type": "function"516 "type": "function"504 },517 },518 {519 "inputs": [],520 "name": "mintingFinished",521 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],522 "stateMutability": "view",523 "type": "function"524 },505 {525 {506 "inputs": [],526 "inputs": [],507 "name": "name",527 "name": "name",tests/src/eth/abi/reFungible.jsondiffbeforeafterboth49 "name": "ApprovalForAll",49 "name": "ApprovalForAll",50 "type": "event"50 "type": "event"51 },51 },52 {53 "anonymous": false,54 "inputs": [],55 "name": "MintingFinished",56 "type": "event"57 },52 {58 {53 "anonymous": false,59 "anonymous": false,54 "inputs": [60 "inputs": [398 "stateMutability": "view",404 "stateMutability": "view",399 "type": "function"405 "type": "function"400 },406 },407 {408 "inputs": [],409 "name": "finishMinting",410 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],411 "stateMutability": "nonpayable",412 "type": "function"413 },401 {414 {402 "inputs": [415 "inputs": [403 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }416 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }484 "stateMutability": "nonpayable",497 "stateMutability": "nonpayable",485 "type": "function"498 "type": "function"486 },499 },500 {501 "inputs": [],502 "name": "mintingFinished",503 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],504 "stateMutability": "view",505 "type": "function"506 },487 {507 {488 "inputs": [],508 "inputs": [],489 "name": "name",509 "name": "name",596 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },616 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },597 { "internalType": "bytes", "name": "data", "type": "bytes" }617 { "internalType": "bytes", "name": "data", "type": "bytes" }598 ],618 ],599 "name": "safeTransferFromWithData",619 "name": "safeTransferFrom",600 "outputs": [],620 "outputs": [],601 "stateMutability": "nonpayable",621 "stateMutability": "nonpayable",602 "type": "function"622 "type": "function"tests/src/eth/abi/reFungibleToken.jsondiffbeforeafterboth96 "stateMutability": "view",96 "stateMutability": "view",97 "type": "function"97 "type": "function"98 },98 },99 {100 "inputs": [101 { "internalType": "address", "name": "from", "type": "address" },102 { "internalType": "uint256", "name": "amount", "type": "uint256" }103 ],104 "name": "burnFrom",105 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],106 "stateMutability": "nonpayable",107 "type": "function"108 },99 {109 {100 "inputs": [110 "inputs": [101 {111 {tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth536}536}537537538/// @title Unique extensions for ERC721.538/// @title Unique extensions for ERC721.539/// @dev the ERC-165 identifier for this interface is 0x0e48fdb4539/// @dev the ERC-165 identifier for this interface is 0x16de3152540interface ERC721UniqueExtensions is Dummy, ERC165 {540interface ERC721UniqueExtensions is Dummy, ERC165 {541 /// @notice A descriptive name for a collection of NFTs in this contract541 /// @notice A descriptive name for a collection of NFTs in this contract542 /// @dev EVM selector for this function is: 0x06fdde03,542 /// @dev EVM selector for this function is: 0x06fdde03,662 /// or in textual repr: mintCross((address,uint256),(string,bytes)[])662 /// or in textual repr: mintCross((address,uint256),(string,bytes)[])663 function mintCross(CrossAddress memory to, Property[] memory properties) external returns (uint256);663 function mintCross(CrossAddress memory to, Property[] memory properties) external returns (uint256);664665 /// @notice Returns collection helper contract address666 /// @dev EVM selector for this function is: 0x1896cce6,667 /// or in textual repr: collectionHelperAddress()668 function collectionHelperAddress() external view returns (address);664}669}665670666/// @dev anonymous struct671/// @dev anonymous struct703708704/// @title ERC-721 Non-Fungible Token Standard709/// @title ERC-721 Non-Fungible Token Standard705/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md710/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md706/// @dev the ERC-165 identifier for this interface is 0x983a942b711/// @dev the ERC-165 identifier for this interface is 0x80ac58cd707interface ERC721 is Dummy, ERC165, ERC721Events {712interface ERC721 is Dummy, ERC165, ERC721Events {708 /// @notice Count all NFTs assigned to an owner713 /// @notice Count all NFTs assigned to an owner709 /// @dev NFTs assigned to the zero address are considered invalid, and this714 /// @dev NFTs assigned to the zero address are considered invalid, and this787 /// or in textual repr: isApprovedForAll(address,address)792 /// or in textual repr: isApprovedForAll(address,address)788 function isApprovedForAll(address owner, address operator) external view returns (bool);793 function isApprovedForAll(address owner, address operator) external view returns (bool);789790 /// @notice Returns collection helper contract address791 /// @dev EVM selector for this function is: 0x1896cce6,792 /// or in textual repr: collectionHelperAddress()793 function collectionHelperAddress() external view returns (address);794}794}795795796interface UniqueNFT is796interface UniqueNFT istests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth441 TransferEnabled441 TransferEnabled442}442}443443444/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension445/// @dev See https://eips.ethereum.org/EIPS/eip-721444/// @dev the ERC-165 identifier for this interface is 0x5b5e139f446/// @dev the ERC-165 identifier for this interface is 0x5b5e139f445interface ERC721Metadata is Dummy, ERC165 {447interface ERC721Metadata is Dummy, ERC165 {446 // /// @notice A descriptive name for a collection of NFTs in this contract448 // /// @notice A descriptive name for a collection of NFTs in this contract534}536}535537536/// @title Unique extensions for ERC721.538/// @title Unique extensions for ERC721.537/// @dev the ERC-165 identifier for this interface is 0xabf30dc2539/// @dev the ERC-165 identifier for this interface is 0xb365c124538interface ERC721UniqueExtensions is Dummy, ERC165 {540interface ERC721UniqueExtensions is Dummy, ERC165 {539 /// @notice A descriptive name for a collection of NFTs in this contract541 /// @notice A descriptive name for a collection of NFTs in this contract540 /// @dev EVM selector for this function is: 0x06fdde03,542 /// @dev EVM selector for this function is: 0x06fdde03,661 /// or in textual repr: tokenContractAddress(uint256)663 /// or in textual repr: tokenContractAddress(uint256)662 function tokenContractAddress(uint256 token) external view returns (address);664 function tokenContractAddress(uint256 token) external view returns (address);665666 /// @notice Returns collection helper contract address667 /// @dev EVM selector for this function is: 0x1896cce6,668 /// or in textual repr: collectionHelperAddress()669 function collectionHelperAddress() external view returns (address);663}670}664671665/// @dev anonymous struct672/// @dev anonymous struct702709703/// @title ERC-721 Non-Fungible Token Standard710/// @title ERC-721 Non-Fungible Token Standard704/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md711/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md705/// @dev the ERC-165 identifier for this interface is 0x4016cd87712/// @dev the ERC-165 identifier for this interface is 0x80ac58cd706interface ERC721 is Dummy, ERC165, ERC721Events {713interface ERC721 is Dummy, ERC165, ERC721Events {707 /// @notice Count all RFTs assigned to an owner714 /// @notice Count all RFTs assigned to an owner708 /// @dev RFTs assigned to the zero address are considered invalid, and this715 /// @dev RFTs assigned to the zero address are considered invalid, and this725 function ownerOf(uint256 tokenId) external view returns (address);732 function ownerOf(uint256 tokenId) external view returns (address);726733727 /// @dev Not implemented734 /// @dev Not implemented728 /// @dev EVM selector for this function is: 0x60a11672,735 /// @dev EVM selector for this function is: 0xb88d4fde,729 /// or in textual repr: safeTransferFromWithData(address,address,uint256,bytes)736 /// or in textual repr: safeTransferFrom(address,address,uint256,bytes)730 function safeTransferFromWithData(737 function safeTransferFrom(731 address from,738 address from,732 address to,739 address to,733 uint256 tokenId,740 uint256 tokenId,784 /// or in textual repr: isApprovedForAll(address,address)791 /// or in textual repr: isApprovedForAll(address,address)785 function isApprovedForAll(address owner, address operator) external view returns (bool);792 function isApprovedForAll(address owner, address operator) external view returns (bool);786787 /// @notice Returns collection helper contract address788 /// @dev EVM selector for this function is: 0x1896cce6,789 /// or in textual repr: collectionHelperAddress()790 function collectionHelperAddress() external view returns (address);791}793}792794793interface UniqueRefungible is795interface UniqueRefungible istests/src/nesting/unnest.test.tsdiffbeforeafterboth161617import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';18import {expect, itSub, Pallets, usingPlaygrounds} from '../util';18import {expect, itSub, Pallets, usingPlaygrounds} from '../util';19import {UniqueFTCollection, UniqueNFToken, UniqueRFToken} from '../util/playgrounds/unique';192020describe('Integration Test: Unnesting', () => {21describe('Integration Test: Unnesting', () => {21 let alice: IKeyringPair;22 let alice: IKeyringPair;23 let bob: IKeyringPair;24 let charlie: IKeyringPair;222523 before(async () => {26 before(async () => {24 await usingPlaygrounds(async (helper, privateKey) => {27 await usingPlaygrounds(async (helper, privateKey) => {25 const donor = await privateKey({filename: __filename});28 const donor = await privateKey({filename: __filename});26 [alice] = await helper.arrange.createAccounts([50n], donor);29 [alice, bob, charlie] = await helper.arrange.createAccounts([200n, 50n, 50n], donor);27 });30 });28 });31 });293264 expect(await targetToken.getChildren()).to.be.length(0);67 expect(await targetToken.getChildren()).to.be.length(0);65 });68 });6970 itSub.ifWithPallets('ReFungible: allows the owner to successfully unnest a token', [Pallets.ReFungible], async ({helper}) => {71 const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});72 const targetToken = await collection.mintToken(alice);7374 const collectionRFT = await helper.rft.mintCollection(alice);7576 // Nest and unnest77 const token = await collectionRFT.mintToken(alice, 10n, targetToken.nestingAccount());78 await expect(token.transferFrom(alice, targetToken.nestingAccount(), {Substrate: alice.address}, 9n), 'while unnesting').to.be.fulfilled;79 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(9n);80 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(1n);8182 // Nest and burn83 await token.transfer(alice, targetToken.nestingAccount(), 5n);84 await expect(token.burnFrom(alice, targetToken.nestingAccount(), 6n), 'while burning').to.be.fulfilled;85 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(4n);86 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(0n);87 expect(await targetToken.getChildren()).to.be.length(0);88 });8990 async function checkNestedAmountState({91 expectedBalance,92 childrenShouldPresent,93 nested,94 targetNft,95 }: {96 expectedBalance: bigint,97 childrenShouldPresent: boolean,98 nested: UniqueFTCollection | UniqueRFToken,99 targetNft: UniqueNFToken,100 }) {101 const balance = await nested.getBalance(targetNft.nestingAccount());102 expect(balance).to.be.equal(expectedBalance);103104 const children = await targetNft.getChildren();105106 if (childrenShouldPresent) {107 expect(children[0]).to.be.deep.equal({108 collectionId: nested.collectionId,109 tokenId: (nested instanceof UniqueFTCollection) ? 0 : nested.tokenId,110 });111 } else {112 expect(children.length).to.be.equal(0);113 }114 }115116 function ownerOrAdminUnnestCases(modes: ('ft' | 'nft' | 'rft')[]): {117 mode: 'ft' | 'nft' | 'rft',118 sender: string,119 op: 'transfer' | 'burn',120 requiredPallets: Pallets[],121 }[] {122 const senders = ['owner', 'admin'];123 const ops = ['transfer', 'burn'];124125 const cases = [];126 for (const mode of modes) {127 const requiredPallets = (mode === 'rft')128 ? [Pallets.ReFungible]129 : [];130131 for (const sender of senders) {132 for (const op of ops) {133 cases.push({134 mode: mode as 'ft' | 'nft' | 'rft',135 sender,136 op: op as 'transfer' | 'burn',137 requiredPallets,138 });139 }140 }141 }142143 return cases;144 }145146 ownerOrAdminUnnestCases(['ft', 'rft']).map(testCase =>147 itSub.ifWithPallets(`[${testCase.mode}]: allows a collection ${testCase.sender} to ${testCase.op} nested token`, testCase.requiredPallets, async({helper}) => {148 const owner = alice;149 const admin = bob;150151 const unnester = (testCase.sender === 'owner')152 ? owner153 : admin;154155 const collectionNFT = await helper.nft.mintCollection(owner);156 await collectionNFT.setPermissions(owner, {nesting: {tokenOwner: true}});157158 const collectionNested = await helper[testCase.mode as 'ft' | 'rft'].mintCollection(owner, {159 limits: {160 ownerCanTransfer: true,161 },162 });163 await collectionNested.addAdmin(owner, {Substrate: admin.address});164165 const targetNft = await collectionNFT.mintToken(owner, {Substrate: charlie.address});166167 let nested: UniqueFTCollection | UniqueRFToken;168 const totalAmount = 5n;169 const firstUnnestAmount = 2n;170 const restUnnestAmount = totalAmount - firstUnnestAmount;171172 if (collectionNested instanceof UniqueFTCollection) {173 await collectionNested.mint(owner, totalAmount, {Substrate: charlie.address});174 nested = collectionNested;175 } else {176 nested = await collectionNested.mintToken(owner, totalAmount, {Substrate: charlie.address});177 }178179 // transfer/burn `amount` of nested assets by `unnester`.180 const doOperationAndCheck = async ({181 amount,182 shouldBeNestedAfterOp,183 }: {184 amount: bigint,185 shouldBeNestedAfterOp: boolean,186 }) => {187 const nestedBalanceBeforeOp = await nested.getBalance(targetNft.nestingAccount());188189 if (testCase.op === 'transfer') {190 const bobBalanceBeforeOp = await nested.getBalance({Substrate: bob.address});191192 await nested.transferFrom(unnester, targetNft.nestingAccount(), {Substrate: bob.address}, amount);193 expect(await nested.getBalance({Substrate: bob.address})).to.be.equal(bobBalanceBeforeOp + amount);194 } else {195 if (nested instanceof UniqueFTCollection) {196 await nested.burnTokensFrom(unnester, targetNft.nestingAccount(), amount);197 } else {198 await nested.burnFrom(unnester, targetNft.nestingAccount(), amount);199 }200 }201202 await checkNestedAmountState({203 expectedBalance: nestedBalanceBeforeOp - amount,204 childrenShouldPresent: shouldBeNestedAfterOp,205 nested,206 targetNft,207 });208 };209210 // Initial setup: nest (fungibles/rft parts).211 // Check NFT's balance of nested assets and NFT's children.212 await nested.transfer(charlie, targetNft.nestingAccount(), totalAmount);213 await checkNestedAmountState({214 expectedBalance: totalAmount,215 childrenShouldPresent: true,216 nested,217 targetNft,218 });219220 // Transfer/burn only a part of nested assets.221 // Check that NFT's balance of the nested assets correctly decreased and NFT's children are not changed.222 await doOperationAndCheck({223 amount: firstUnnestAmount,224 shouldBeNestedAfterOp: true,225 });226227 // Transfer/burn all remaining nested assets.228 // Check that NFT's balance of the nested assets is 0 and NFT has no more children.229 await doOperationAndCheck({230 amount: restUnnestAmount,231 shouldBeNestedAfterOp: false,232 });233 }));234235 ownerOrAdminUnnestCases(['nft']).map(testCase =>236 itSub(`[nft]: allows a collection ${testCase.sender} to ${testCase.op} nested token`, async ({helper}) => {237 const owner = alice;238 const admin = bob;239240 const unnester = (testCase.sender === 'owner')241 ? owner242 : admin;243244 const collectionNFT = await helper.nft.mintCollection(owner);245 await collectionNFT.setPermissions(owner, {nesting: {tokenOwner: true}});246247 const collectionNested = await helper.nft.mintCollection(owner, {248 limits: {249 ownerCanTransfer: true,250 },251 });252 await collectionNested.addAdmin(owner, {Substrate: admin.address});253254 const targetNft = await collectionNFT.mintToken(owner, {Substrate: charlie.address});255 const nested = await collectionNested.mintToken(owner, {Substrate: charlie.address});256257 await nested.transfer(charlie, targetNft.nestingAccount());258 expect(await targetNft.getChildren()).to.be.deep.equal([{259 collectionId: nested.collectionId,260 tokenId: nested.tokenId,261 }]);262263 if (testCase.op === 'transfer') {264 await nested.transferFrom(unnester, targetNft.nestingAccount(), {Substrate: bob.address});265 } else {266 await nested.burnFrom(unnester, targetNft.nestingAccount());267 }268269 expect((await targetNft.getChildren()).length).to.be.equal(0);270 }));66});271});6727268describe('Negative Test: Unnesting', () => {273describe('Negative Test: Unnesting', () => {tests/src/pallet-presence.test.tsdiffbeforeafterboth76 appPromotion,76 appPromotion,77 testUtils,77 testUtils,78 ...rmrkPallets,78 ...rmrkPallets,79 ...collatorSelection,79 );80 );80 } else if (chain.eq('QUARTZ by UNIQUE') || chain.eq('SAPPHIRE by UNIQUE')) {81 } else if (chain.eq('QUARTZ by UNIQUE') || chain.eq('SAPPHIRE by UNIQUE')) {81 requiredPallets.push(82 requiredPallets.push(tests/src/util/playgrounds/unique.tsdiffbeforeafterboth651 try {651 try {652 result = await this.signTransaction(sender, this.constructApiCall(extrinsic, params), options, extrinsic) as ITransactionResult;652 result = await this.signTransaction(sender, this.constructApiCall(extrinsic, params), options, extrinsic) as ITransactionResult;653 events = this.eventHelper.extractEvents(result.result.events);653 events = this.eventHelper.extractEvents(result.result.events);654 const errorEvent = events.find((event) => event.method == 'ExecutedFailed' || event.method == 'CreatedFailed');655 if (errorEvent)656 throw Error(errorEvent.method + ': ' + extrinsic);654 }657 }655 catch(e) {658 catch(e) {656 if(!(e as object).hasOwnProperty('status')) throw e;659 if(!(e as object).hasOwnProperty('status')) throw e;