github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/evm/handler/coa/coa.sol (about) 1 // SPDX-License-Identifier: UNLICENSED 2 3 pragma solidity >=0.7.0 <0.9.0; 4 5 interface IERC165 { 6 function supportsInterface(bytes4 interfaceId) external view returns (bool); 7 } 8 9 interface ERC721TokenReceiver { 10 function onERC721Received( 11 address _operator, 12 address _from, 13 uint256 _tokenId, 14 bytes calldata _data 15 ) external returns (bytes4); 16 } 17 18 interface ERC777TokensRecipient { 19 function tokensReceived( 20 address operator, 21 address from, 22 address to, 23 uint256 amount, 24 bytes calldata data, 25 bytes calldata operatorData 26 ) external; 27 } 28 29 interface ERC1155TokenReceiver { 30 31 function onERC1155Received( 32 address _operator, 33 address _from, 34 uint256 _id, 35 uint256 _value, 36 bytes calldata _data 37 ) external returns (bytes4); 38 39 function onERC1155BatchReceived( 40 address _operator, 41 address _from, 42 uint256[] calldata _ids, 43 uint256[] calldata _values, 44 bytes calldata _data 45 ) external returns (bytes4); 46 47 } 48 49 contract COA is ERC1155TokenReceiver, ERC777TokensRecipient, ERC721TokenReceiver, IERC165 { 50 address constant public cadenceArch = 0x0000000000000000000000010000000000000001; 51 52 // bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) 53 bytes4 constant internal ERC721ReceivedIsSupported = 0x150b7a02; 54 55 // bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)")) 56 bytes4 constant internal ERC1155ReceivedIsSupported = 0xf23a6e61; 57 58 // bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)")) 59 bytes4 constant internal ERC1155BatchReceivedIsSupported = 0xbc197c81; 60 61 // bytes4(keccak256("isValidSignature(bytes32,bytes)") 62 bytes4 constant internal ValidERC1271Signature = 0x1626ba7e; 63 bytes4 constant internal InvalidERC1271Signature = 0xffffffff; 64 65 receive() external payable { 66 } 67 function supportsInterface(bytes4 id) external view virtual override returns (bool) { 68 return 69 id == type(ERC1155TokenReceiver).interfaceId || 70 id == type(ERC721TokenReceiver).interfaceId || 71 id == type(ERC777TokensRecipient).interfaceId || 72 id == type(IERC165).interfaceId; 73 } 74 75 function tokensReceived( 76 address, 77 address, 78 address, 79 uint256, 80 bytes calldata, 81 bytes calldata 82 ) external pure override {} 83 84 function onERC721Received( 85 address, 86 address, 87 uint256, 88 bytes calldata 89 ) external pure override returns (bytes4) { 90 return ERC721ReceivedIsSupported; 91 } 92 93 function onERC1155Received( 94 address, 95 address, 96 uint256, 97 uint256, 98 bytes calldata 99 ) external pure override returns (bytes4) { 100 return ERC1155ReceivedIsSupported; 101 } 102 103 function onERC1155BatchReceived( 104 address, 105 address, 106 uint256[] calldata, 107 uint256[] calldata, 108 bytes calldata 109 ) external pure override returns (bytes4) { 110 return ERC1155BatchReceivedIsSupported; 111 } 112 113 // ERC1271 requirement 114 function isValidSignature( 115 bytes32 _hash, 116 bytes memory _sig 117 ) external view virtual returns (bytes4){ 118 (bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("verifyCOAOwnershipProof(address,bytes32,bytes)", address(this), _hash, _sig)); 119 require(ok); 120 bool output = abi.decode(data, (bool)); 121 if (output) { 122 return ValidERC1271Signature; 123 } 124 return InvalidERC1271Signature; 125 } 126 }