--- a/.maintain/scripts/compile_stub.sh +++ b/.maintain/scripts/compile_stub.sh @@ -6,9 +6,9 @@ tmp=$(mktemp -d) cd $tmp cp $dir/$INPUT input.sol -solcjs --optimize --bin input.sol +solcjs --optimize --bin input.sol -o $PWD mv input_sol_$(basename $OUTPUT .raw).bin out.bin xxd -r -p out.bin out.raw -mv out.raw $dir/$OUTPUT \ No newline at end of file +mv out.raw $dir/$OUTPUT --- a/.maintain/scripts/generate_api.sh +++ b/.maintain/scripts/generate_api.sh @@ -9,4 +9,4 @@ prettier --use-tabs $raw > $formatted solhint --fix $formatted -mv $formatted $OUTPUT \ No newline at end of file +mv $formatted $OUTPUT --- a/Makefile +++ b/Makefile @@ -8,25 +8,26 @@ .PHONY: regenerate_solidity regenerate_solidity: - PACKAGE=pallet-nft NAME=eth::erc::fungible_iface OUTPUT=./tests/src/eth/api/UniqueFungible.sol ./.maintain/scripts/generate_api.sh - PACKAGE=pallet-nft NAME=eth::erc::nft_iface OUTPUT=./tests/src/eth/api/UniqueNFT.sol ./.maintain/scripts/generate_api.sh + PACKAGE=pallet-fungible NAME=erc::gen_iface OUTPUT=./tests/src/eth/api/UniqueFungible.sol ./.maintain/scripts/generate_api.sh + PACKAGE=pallet-nonfungible NAME=erc::gen_iface OUTPUT=./tests/src/eth/api/UniqueNFT.sol ./.maintain/scripts/generate_api.sh PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_iface OUTPUT=./tests/src/eth/api/ContractHelpers.sol ./.maintain/scripts/generate_api.sh - PACKAGE=pallet-nft NAME=eth::erc::fungible_impl OUTPUT=./pallets/nft/src/eth/stubs/UniqueFungible.sol ./.maintain/scripts/generate_api.sh - PACKAGE=pallet-nft NAME=eth::erc::nft_impl OUTPUT=./pallets/nft/src/eth/stubs/UniqueNFT.sol ./.maintain/scripts/generate_api.sh + PACKAGE=pallet-fungible NAME=erc::gen_impl OUTPUT=./pallets/fungible/src/stubs/UniqueFungible.sol ./.maintain/scripts/generate_api.sh + PACKAGE=pallet-nonfungible NAME=erc::gen_impl OUTPUT=./pallets/nonfungible/src/stubs/UniqueNFT.sol ./.maintain/scripts/generate_api.sh PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_impl OUTPUT=./pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol ./.maintain/scripts/generate_api.sh -NFT_EVM_STUBS=./pallets/nft/src/eth/stubs +FUNGIBLE_EVM_STUBS=./pallets/fungible/src/stubs +NONFUNGIBLE_EVM_STUBS=./pallets/nonfungible/src/stubs CONTRACT_HELPERS_STUBS=./pallets/evm-contract-helpers/src/stubs/ -$(NFT_EVM_STUBS)/UniqueFungible.raw: $(NFT_EVM_STUBS)/UniqueFungible.sol +$(FUNGIBLE_EVM_STUBS)/UniqueFungible.raw: $(FUNGIBLE_EVM_STUBS)/UniqueFungible.sol INPUT=$< OUTPUT=$@ ./.maintain/scripts/compile_stub.sh -$(NFT_EVM_STUBS)/UniqueNFT.raw: $(NFT_EVM_STUBS)/UniqueNFT.sol +$(NONFUNGIBLE_EVM_STUBS)/UniqueNFT.raw: $(NONFUNGIBLE_EVM_STUBS)/UniqueNFT.sol INPUT=$< OUTPUT=$@ ./.maintain/scripts/compile_stub.sh $(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw: $(CONTRACT_HELPERS_STUBS)/ContractHelpers.sol INPUT=$< OUTPUT=$@ ./.maintain/scripts/compile_stub.sh -evm_stubs: $(NFT_EVM_STUBS)/UniqueFungible.raw $(NFT_EVM_STUBS)/UniqueNFT.raw $(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw +evm_stubs: $(FUNGIBLE_EVM_STUBS)/UniqueFungible.raw $(NONFUNGIBLE_EVM_STUBS)/UniqueNFT.raw $(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw .PHONY: _bench _bench: --- a/crates/evm-coder-macros/src/solidity_interface.rs +++ b/crates/evm-coder-macros/src/solidity_interface.rs @@ -714,9 +714,9 @@ )*), }; if is_impl { - tc.collect("// Common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ninterface ERC165 {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n".into()); + tc.collect("// Common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n".into()); } else { - tc.collect("// Common stubs holder\ninterface Dummy {\n}\ninterface ERC165 {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n".into()); + tc.collect("// Common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n".into()); } #( #solidity_generators --- a/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol +++ b/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol @@ -9,7 +9,19 @@ string stub_error = "this contract is implemented in native"; } -contract ContractHelpers is Dummy { +contract ERC165 is Dummy { + function supportsInterface(bytes4 interfaceID) + external + view + returns (bool) + { + require(false, stub_error); + interfaceID; + return true; + } +} + +contract ContractHelpers is Dummy, ERC165 { // Selector: contractOwner(address) 5152b14c function contractOwner(address contractAddress) public --- a/pallets/fungible/Cargo.toml +++ b/pallets/fungible/Cargo.toml @@ -18,8 +18,8 @@ pallet-common = { default-features = false, path = '../common' } nft-data-structs = { default-features = false, path = '../../primitives/nft' } evm-coder = { default-features = false, path = '../../crates/evm-coder' } +pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' } ethereum = { git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false } -pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' } frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } scale-info = { version = "1.0.0", default-features = false, features = [ "derive", @@ -36,6 +36,7 @@ "pallet-common/std", "evm-coder/std", "ethereum/std", + "pallet-evm-coder-substrate/std", 'frame-benchmarking/std', ] runtime-benchmarks = ['frame-benchmarking', 'pallet-common/runtime-benchmarks'] --- a/pallets/fungible/src/erc.rs +++ b/pallets/fungible/src/erc.rs @@ -111,7 +111,7 @@ #[solidity_interface(name = "UniqueFungible", is(ERC20))] impl FungibleHandle {} -generate_stubgen!(get_impl, UniqueFungibleCall, true); +generate_stubgen!(gen_impl, UniqueFungibleCall, true); generate_stubgen!(gen_iface, UniqueFungibleCall, false); impl CommonEvmHandler for FungibleHandle { --- a/pallets/fungible/src/stubs/UniqueFungible.sol +++ b/pallets/fungible/src/stubs/UniqueFungible.sol @@ -9,6 +9,18 @@ string stub_error = "this contract is implemented in native"; } +contract ERC165 is Dummy { + function supportsInterface(bytes4 interfaceID) + external + view + returns (bool) + { + require(false, stub_error); + interfaceID; + return true; + } +} + // Inline contract ERC20Events { event Transfer(address indexed from, address indexed to, uint256 value); @@ -19,8 +31,7 @@ ); } -// Inline -contract InlineNameSymbol is Dummy { +contract ERC20 is Dummy, ERC165, ERC20Events { // Selector: name() 06fdde03 function name() public view returns (string memory) { require(false, stub_error); @@ -34,29 +45,14 @@ dummy; return ""; } -} -// Inline -contract InlineTotalSupply is Dummy { // Selector: totalSupply() 18160ddd function totalSupply() public view returns (uint256) { require(false, stub_error); dummy; return 0; } -} -contract ERC165 is Dummy { - // Selector: supportsInterface(bytes4) 01ffc9a7 - function supportsInterface(uint32 interfaceId) public view returns (bool) { - require(false, stub_error); - interfaceId; - dummy; - return false; - } -} - -contract ERC20 is Dummy, InlineNameSymbol, InlineTotalSupply, ERC20Events { // Selector: decimals() 313ce567 function decimals() public view returns (uint8) { require(false, stub_error); --- a/pallets/nonfungible/src/stubs/UniqueNFT.sol +++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol @@ -15,6 +15,18 @@ string stub_error = "this contract is implemented in native"; } +contract ERC165 is Dummy { + function supportsInterface(bytes4 interfaceID) + external + view + returns (bool) + { + require(false, stub_error); + interfaceID; + return true; + } +} + // Inline contract ERC721Events { event Transfer( @@ -37,43 +49,6 @@ // Inline contract ERC721MintableEvents { event MintingFinished(); -} - -// Inline -contract InlineNameSymbol is Dummy { - // Selector: name() 06fdde03 - function name() public view returns (string memory) { - require(false, stub_error); - dummy; - return ""; - } - - // Selector: symbol() 95d89b41 - function symbol() public view returns (string memory) { - require(false, stub_error); - dummy; - return ""; - } -} - -// Inline -contract InlineTotalSupply is Dummy { - // Selector: totalSupply() 18160ddd - function totalSupply() public view returns (uint256) { - require(false, stub_error); - dummy; - return 0; - } -} - -contract ERC165 is Dummy { - // Selector: supportsInterface(bytes4) 01ffc9a7 - function supportsInterface(uint32 interfaceId) public view returns (bool) { - require(false, stub_error); - interfaceId; - dummy; - return false; - } } contract ERC721 is Dummy, ERC165, ERC721Events { @@ -172,7 +147,7 @@ } } -contract ERC721Burnable is Dummy { +contract ERC721Burnable is Dummy, ERC165 { // Selector: burn(uint256) 42966c68 function burn(uint256 tokenId) public { require(false, stub_error); @@ -181,7 +156,7 @@ } } -contract ERC721Enumerable is Dummy, InlineTotalSupply { +contract ERC721Enumerable is Dummy, ERC165 { // Selector: tokenByIndex(uint256) 4f6ccce7 function tokenByIndex(uint256 index) public view returns (uint256) { require(false, stub_error); @@ -202,9 +177,30 @@ dummy; return 0; } + + // Selector: totalSupply() 18160ddd + function totalSupply() public view returns (uint256) { + require(false, stub_error); + dummy; + return 0; + } } -contract ERC721Metadata is Dummy, InlineNameSymbol { +contract ERC721Metadata is Dummy, ERC165 { + // Selector: name() 06fdde03 + function name() public view returns (string memory) { + require(false, stub_error); + dummy; + return ""; + } + + // Selector: symbol() 95d89b41 + function symbol() public view returns (string memory) { + require(false, stub_error); + dummy; + return ""; + } + // Selector: tokenURI(uint256) c87b56dd function tokenURI(uint256 tokenId) public view returns (string memory) { require(false, stub_error); @@ -214,7 +210,7 @@ } } -contract ERC721Mintable is Dummy, ERC721MintableEvents { +contract ERC721Mintable is Dummy, ERC165, ERC721MintableEvents { // Selector: mintingFinished() 05d2035b function mintingFinished() public view returns (bool) { require(false, stub_error); @@ -253,7 +249,7 @@ } } -contract ERC721UniqueExtensions is Dummy { +contract ERC721UniqueExtensions is Dummy, ERC165 { // Selector: transfer(address,uint256) a9059cbb function transfer(address to, uint256 tokenId) public { require(false, stub_error); @@ -262,6 +258,14 @@ dummy = 0; } + // Selector: burnFrom(address,uint256) 79cc6790 + function burnFrom(address from, uint256 tokenId) public { + require(false, stub_error); + from; + tokenId; + dummy = 0; + } + // Selector: nextTokenId() 75794a3c function nextTokenId() public view returns (uint256) { require(false, stub_error); --- a/tests/src/eth/api/ContractHelpers.sol +++ b/tests/src/eth/api/ContractHelpers.sol @@ -8,7 +8,11 @@ } -interface ContractHelpers is Dummy { +interface ERC165 is Dummy { + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} + +interface ContractHelpers is Dummy, ERC165 { // Selector: contractOwner(address) 5152b14c function contractOwner(address contractAddress) external --- a/tests/src/eth/api/UniqueFungible.sol +++ b/tests/src/eth/api/UniqueFungible.sol @@ -8,6 +8,10 @@ } +interface ERC165 is Dummy { + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} + // Inline interface ERC20Events { event Transfer(address indexed from, address indexed to, uint256 value); @@ -18,27 +22,16 @@ ); } -// Inline -interface InlineNameSymbol is Dummy { +interface ERC20 is Dummy, ERC165, ERC20Events { // Selector: name() 06fdde03 function name() external view returns (string memory); // Selector: symbol() 95d89b41 function symbol() external view returns (string memory); -} -// Inline -interface InlineTotalSupply is Dummy { // Selector: totalSupply() 18160ddd function totalSupply() external view returns (uint256); -} - -interface ERC165 is Dummy { - // Selector: supportsInterface(bytes4) 01ffc9a7 - function supportsInterface(uint32 interfaceId) external view returns (bool); -} -interface ERC20 is Dummy, InlineNameSymbol, InlineTotalSupply, ERC20Events { // Selector: decimals() 313ce567 function decimals() external view returns (uint8); --- a/tests/src/eth/api/UniqueNFT.sol +++ b/tests/src/eth/api/UniqueNFT.sol @@ -14,6 +14,10 @@ } +interface ERC165 is Dummy { + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} + // Inline interface ERC721Events { event Transfer( @@ -36,26 +40,6 @@ // Inline interface ERC721MintableEvents { event MintingFinished(); -} - -// Inline -interface InlineNameSymbol is Dummy { - // Selector: name() 06fdde03 - function name() external view returns (string memory); - - // Selector: symbol() 95d89b41 - function symbol() external view returns (string memory); -} - -// Inline -interface InlineTotalSupply is Dummy { - // Selector: totalSupply() 18160ddd - function totalSupply() external view returns (uint256); -} - -interface ERC165 is Dummy { - // Selector: supportsInterface(bytes4) 01ffc9a7 - function supportsInterface(uint32 interfaceId) external view returns (bool); } interface ERC721 is Dummy, ERC165, ERC721Events { @@ -103,12 +87,12 @@ returns (address); } -interface ERC721Burnable is Dummy { +interface ERC721Burnable is Dummy, ERC165 { // Selector: burn(uint256) 42966c68 function burn(uint256 tokenId) external; } -interface ERC721Enumerable is Dummy, InlineTotalSupply { +interface ERC721Enumerable is Dummy, ERC165 { // Selector: tokenByIndex(uint256) 4f6ccce7 function tokenByIndex(uint256 index) external view returns (uint256); @@ -117,14 +101,23 @@ external view returns (uint256); + + // Selector: totalSupply() 18160ddd + function totalSupply() external view returns (uint256); } -interface ERC721Metadata is Dummy, InlineNameSymbol { +interface ERC721Metadata is Dummy, ERC165 { + // Selector: name() 06fdde03 + function name() external view returns (string memory); + + // Selector: symbol() 95d89b41 + function symbol() external view returns (string memory); + // Selector: tokenURI(uint256) c87b56dd function tokenURI(uint256 tokenId) external view returns (string memory); } -interface ERC721Mintable is Dummy, ERC721MintableEvents { +interface ERC721Mintable is Dummy, ERC165, ERC721MintableEvents { // Selector: mintingFinished() 05d2035b function mintingFinished() external view returns (bool); @@ -142,10 +135,13 @@ function finishMinting() external returns (bool); } -interface ERC721UniqueExtensions is Dummy { +interface ERC721UniqueExtensions is Dummy, ERC165 { // Selector: transfer(address,uint256) a9059cbb function transfer(address to, uint256 tokenId) external; + // Selector: burnFrom(address,uint256) 79cc6790 + function burnFrom(address from, uint256 tokenId) external; + // Selector: nextTokenId() 75794a3c function nextTokenId() external view returns (uint256);