From 571d3aab99b0b3d7973a80a5de560e1072bb7655 Mon Sep 17 00:00:00 2001 From: xiang <308260887@qq.com> Date: Wed, 21 Jun 2023 17:24:54 +0800 Subject: [PATCH 1/9] Create eip-walletmanagementtoken.md --- EIPS/eip-walletmanagementtoken.md | 291 ++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 EIPS/eip-walletmanagementtoken.md diff --git a/EIPS/eip-walletmanagementtoken.md b/EIPS/eip-walletmanagementtoken.md new file mode 100644 index 0000000000000..91be2da7b0607 --- /dev/null +++ b/EIPS/eip-walletmanagementtoken.md @@ -0,0 +1,291 @@ +--- +title: Smart contract wallet management asset interface +description: for fungible tokens +author: Xiang (@wenzhenxiang), Ben77 (@ben2077), Mingshi S. (@newnewsms) +discussions-to: https://ethereum-magicians.org/t/simple-token-designed-for-smart-contract-wallet-aa/14757 +status: Draft +type: Standards Track +category: ERC +created: 2023-06-21 +requires: 165 +--- + +## Abstract + +A proposal to manage fungible tokens by the user's smart contract wallet, which provides a new way to manage assets, utilizes the programmability of the smart contract wallet, and also provides more playability. + +## Motivation + +EOA wallet has no state and code storage, and the smart contract wallet is different. + +AA is a direction of the smart contract wallet, which works around abstract accounts. This EIP can also be an extension based on [EIP-4337](./eip-4337.md). + +The smart contract wallet allows the user's own account to have state and code, bringing programmability to the wallet. We think there are more directions to expand. For example, token asset management, functional expansion of token transactions, etc. + +The smart contract wallet interface of this EIP is for asset management and asset approval. It supports the new asset EIP-X, and [ERC-20](./eip-20.md) is backward compatible with EIP-X, so it can be compatible with the management of all fungible tokens in the existing market. + +The proposal aims to achieve the following goals: + +1. Assets are allocated and managed by the wallet itself, such as approve and allowance, which are configured by the user’s contract wallet, rather than controlled by the token asset contract, to avoid some existing ERC-20 contract risks. +2. Add the transferFungibleToken function, the transaction initiated by the non-smart wallet itself or will verify the allowance state. +3. Users can choose batch approve and batch transfer. Batch approve can greatly reduce gas. The contract wallet itself manages the authorization status of all assets, and batch approve can be performed without calling multiple token contracts. +4. Users can choose to add hook function before and after their transferFungibleToken to increase the user's more playability. +5. User can choose to implement the receiveFungibleToken function. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +**Every ERC-Y compliant contract must implement the ERC-Y and [ERC-165](./eip-165) interfaces** + +```solidity +/// @title ERC-Y +/// @dev See https://eips.ethereum.org/EIPS/eip-Y +/// @dev Note: the ERC-165 identifier for this interface is 0xf73edcda +pragma solidity ^0.8.20; + +interface IERCY /* is ERC165 */ { + + /** + * @notice Used to notify listeners that owner has granted approval to the user to manage assets tokens. + * @param asset Address of the fungible token + * @param owner Address of the account that has granted the approval for token‘s assets + * @param spender Address of the spender + * @param value The amount allowed to spend + */ + event ApprovalFungibleToken( + address indexed asset, + address indexed owner, + address indexed spender, + uint256 value + ); + + /** + * @notice Approve fungible token + * @dev Allows spender address to withdraw from your account multiple times, up to the value amount. + * @dev If this function is called again it overwrites the current allowance with value. + * @dev Emits an {ApprovalFungibleToken} event. + * @param asset Address of the fungible token + * @param spender Address of the spender + * @param value The amount allowed to spend + * @return success The bool value returns whether the approve is successful + */ + function approveFungibleToken(address asset, address spender, uint256 value) + external + returns (bool success); + + /** + * @notice Transfer fungible token + * @dev must call asset.transfer() inside the function + * @dev If the caller is not yourself, must verify the allowance and update the allowance value + * @param asset Address of the fungible token + * @param to Address of the receive + * @param value The transaction amount + * @return success The bool value returns whether the transfer is successful + */ + function transferFungibleToken(address asset, address to, uint256 value) + external + returns (bool success); + + + /** + * @notice Transfer fungible token + * @param asset Address of the fungible token + * @param spender Address of the spender + * @return remaining The asset amount which spender is still allowed to withdraw from owner. + */ + function allowanceFungibleToken(address asset, address spender) + external + view + returns (uint256 remaining); + +} +``` + +Batch operation extension is OPTIONAL, here allows batch transfer and batch approve. Smart contracts MUST implement the ERC-165 supportsInterface function. + +```solidity +/// @title ERC-YBatch +/// @dev See https://eips.ethereum.org/EIPS/eip-Y +/// @dev Note: the ERC-165 identifier for this interface is 0xaae6c42c + +pragma solidity ^0.8.20; + +interface IERCYBatch /* is ERC165 */ { + + /** + * @notice Batch approve fungible token + * @dev Allows spender address to withdraw from your account multiple times, up to the value amount. + * @dev If this function is called again it overwrites the current allowance with value. + * @dev Emits an {ApprovalFungibleToken} event. + * @param assets Address of the fungible token + * @param spenders Address of the spender + * @param values The amount allowed to spend + * @return success The bool value returns whether the batch approve is successful + */ + function approveBacthFungibleToken(address[] memory assets, address[] memory spenders, uint256[] memory values) + external + returns (bool success); + + /** + * @notice Batch transfer fungible token + * @dev If the caller is not yourself, must verify the allowance and update the allowance value + * @param assets Addresses of the fungible token + * @param tos Addresses of the receive + * @param values value of the transaction amount + * @return success The bool value returns whether the batch transfer is successful + */ + function transferBatchFungibleToken(address[] memory assets, address[] memory tos, uint256[] memory values) + external + returns (bool success); +} +``` + +## Rationale + +Use the sequence diagram to compare the difference between using this interface to transfer tokens. + +**Alice calls the transfer herself** + +The user does not use this EIP to call the transaction sequence diagram(transfer). + +```mermaid +sequenceDiagram + autonumber + Alice's EOA->>Token Asset Contract: call transfer,update balance state + +``` + +The user use this EIP to call the transaction sequence diagram( Alice's AA implements this EIP), dotted lines are optional. + +```mermaid +sequenceDiagram + autonumber + Alice's AA-->>Alice's AA: call transferFungibleToken + Alice's AA-->>Alice's AA: call protransfer + Alice's AA->>Token Contract: call transfer,update balance state + Token Contract-->>Bob's AA : call receiveFungibleToken + Bob's AA -->> Alice's AA: + Alice's AA -->>Alice's AA: call posttransfer + + +``` + +**Alice doesn't call the transfer herself** + +Sequence diagram of third party calling user transaction without using this EIP(transferForm). + +```mermaid +sequenceDiagram + autonumber + Alice's EOA->>Token Contract: call approve + Alice's EOA->>Defi Contract: call staking + Defi Contract ->>Token Contract: call transferFrom,update allowance state + Token Contract ->> Token Contract: call transfer,update balance state +``` + +Sequence diagram of third party calling user transaction using this EIP(transferFungibleToken). + +```mermaid +sequenceDiagram + autonumber + Alice's AA->>Alice's AA: call approveFungibleToken + Alice's AA->>Defi Contract: call staking + Defi Contract->>Alice's AA: call transferFungibleToken,update allowance state + Alice's AA ->> Token Contract: call transfer,update balance state +``` + +The third party uses this EIP and is compatible with the old dapp protocol and EOA to call the user transaction sequence diagram(transferForm). + +```mermaid +sequenceDiagram + autonumber + Alice's AA->>Alice's AA: call approveFungibleToken + Alice's AA->>Defi Contract: call staking + Defi Contract ->>Token Contract: call transferFrom + Token Contract->>Alice's AA: call transferFungibleToken,update allowance state + Alice's AA ->> Token Contract: call transfer,update balance state +``` + +## Backwards Compatibility + +This EIP can be used as an extension of EIP-4337 and is backward compatible with EIP-4337. + +## Reference Implementation + +```solidity +contract ERCY is IERCY,IERCYBatch,ERC165{ + + mapping (address => mapping (address => uint256)) private _allowances; + + bytes4 constant private INTERFACE_SIGNATURE_ERC165 = 0x01ffc9a7; + bytes4 constant private INTERFACE_SIGNATURE_ERCY = 0xf73edcda; + bytes4 constant private INTERFACE_SIGNATURE_ERCYBATCH = 0xaae6c42c; + + function supportsInterface(bytes4 _interfaceId) public pure returns (bool) { + if (_interfaceId == INTERFACE_SIGNATURE_ERC165 || + _interfaceId == INTERFACE_SIGNATURE_ERCY || + _interfaceId == INTERFACE_SIGNATURE_ERCYBATCH) { + return true; + } + return false; + } + + function transferFungibleToken(address _asset, address _to, uint256 _value) public returns (bool) { + // msg.sender + if (!isMyAccount(msg.sender)){ + require(_value <= _allowances[_asset][_to], "transfer amount exceeds allowance"); + approveFungibleToken(_asset, _to, _allowances[_asset][_to] - _value); + } + require(IERCX(_asset).transfer(_to, _value),"ERC-20 transfer failed"); + return true; + } + + function approveFungibleToken(address _asset, address _spender, uint256 _value) public returns (bool) { + require(isMyAccount(msg.sender), "not my account"); + _allowances[_asset][_spender] = _value; + emit ApprovalFungibleToken(_asset, address(this), _spender, _value); + return true; + } + function transferBatchFungibleToken(address[] memory _assets, address[] memory _tos, uint256[] memory _values) external returns (bool) { + require(_assets.length == _tos.length, "length mismatch"); + require(_tos.length == _values.length, "length mismatch"); + for (uint i = 0; i < _assets.length; i++) { + transferFungibleToken(_assets[i],_tos[i],_values[i]); + } + return true; + } + + function approveBacthFungibleToken(address[] memory _asset, address[] memory _spender, uint256[] memory _value) public returns (bool) { + require(_asset.length == _spender.length, "length mismatch"); + require(_spender.length == _value.length, "length mismatch"); + require(isMyAccount(msg.sender), "not my account"); + for (uint i = 0; i < _asset.length; i++) { + // Allowance for the owner to spender is already 0 in ERC-20 + // So, we don't need to set allowance to 0 before setting a new value + _allowances[_asset[i]][_spender[i]] = _value[i]; + emit ApprovalFungibleToken(_asset[i], address(this), _spender[i], _value[i]); + } + + return true; + } + + function allowanceFungibleToken(address _asset, address _spender) public view returns (uint256) { + return _allowances[_asset][_spender]; + } + + function isMyAccount(address _account) internal pure returns (bool) { + return true; + } + +} +``` + + +## Security Considerations + +No security considerations were found. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 16f88316dee408f0296d1462b59ce3d6d8dccd7c Mon Sep 17 00:00:00 2001 From: xiang <308260887@qq.com> Date: Wed, 21 Jun 2023 17:29:41 +0800 Subject: [PATCH 2/9] Update and rename eip-walletmanagementtoken.md to eip-8888.md --- EIPS/{eip-walletmanagementtoken.md => eip-8888.md} | 1 + 1 file changed, 1 insertion(+) rename EIPS/{eip-walletmanagementtoken.md => eip-8888.md} (99%) diff --git a/EIPS/eip-walletmanagementtoken.md b/EIPS/eip-8888.md similarity index 99% rename from EIPS/eip-walletmanagementtoken.md rename to EIPS/eip-8888.md index 91be2da7b0607..a3b8a15440629 100644 --- a/EIPS/eip-walletmanagementtoken.md +++ b/EIPS/eip-8888.md @@ -1,4 +1,5 @@ --- +eip: 8888 title: Smart contract wallet management asset interface description: for fungible tokens author: Xiang (@wenzhenxiang), Ben77 (@ben2077), Mingshi S. (@newnewsms) From d91540a4a82799c8d2b51e38c8fb29c23291f9e6 Mon Sep 17 00:00:00 2001 From: xiang <308260887@qq.com> Date: Wed, 21 Jun 2023 17:32:09 +0800 Subject: [PATCH 3/9] Update eip-8888.md --- EIPS/eip-8888.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-8888.md b/EIPS/eip-8888.md index a3b8a15440629..9a95e4428c8c1 100644 --- a/EIPS/eip-8888.md +++ b/EIPS/eip-8888.md @@ -1,7 +1,7 @@ --- eip: 8888 -title: Smart contract wallet management asset interface -description: for fungible tokens +title: contract wallet management asset +description: fungible tokens author: Xiang (@wenzhenxiang), Ben77 (@ben2077), Mingshi S. (@newnewsms) discussions-to: https://ethereum-magicians.org/t/simple-token-designed-for-smart-contract-wallet-aa/14757 status: Draft From b5a9a39a7bce8eb1ae1f447b22fd500d6e7f7311 Mon Sep 17 00:00:00 2001 From: xiang <308260887@qq.com> Date: Wed, 21 Jun 2023 17:34:19 +0800 Subject: [PATCH 4/9] Update eip-8888.md --- EIPS/eip-8888.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-8888.md b/EIPS/eip-8888.md index 9a95e4428c8c1..735761c45b2b2 100644 --- a/EIPS/eip-8888.md +++ b/EIPS/eip-8888.md @@ -1,9 +1,9 @@ --- eip: 8888 title: contract wallet management asset -description: fungible tokens +description: fungible tokens author: Xiang (@wenzhenxiang), Ben77 (@ben2077), Mingshi S. (@newnewsms) -discussions-to: https://ethereum-magicians.org/t/simple-token-designed-for-smart-contract-wallet-aa/14757 +discussions-to: [https://ethereum-magicians.org/t/simple-token-designed-for-smart-contract-wallet-aa/14757](https://ethereum-magicians.org/t/token-asset-management-interface-with-smart-contract-wallet/14759) status: Draft type: Standards Track category: ERC From fb6e297a36f9fd6b51f345bf0b6036064fced393 Mon Sep 17 00:00:00 2001 From: xiang <308260887@qq.com> Date: Wed, 21 Jun 2023 17:35:19 +0800 Subject: [PATCH 5/9] Update eip-8888.md --- EIPS/eip-8888.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-8888.md b/EIPS/eip-8888.md index 735761c45b2b2..0fa31be3338d9 100644 --- a/EIPS/eip-8888.md +++ b/EIPS/eip-8888.md @@ -3,7 +3,7 @@ eip: 8888 title: contract wallet management asset description: fungible tokens author: Xiang (@wenzhenxiang), Ben77 (@ben2077), Mingshi S. (@newnewsms) -discussions-to: [https://ethereum-magicians.org/t/simple-token-designed-for-smart-contract-wallet-aa/14757](https://ethereum-magicians.org/t/token-asset-management-interface-with-smart-contract-wallet/14759) +discussions-to: https://ethereum-magicians.org/t/token-asset-management-interface-with-smart-contract-wallet/14759 status: Draft type: Standards Track category: ERC From a235e23503b23082da03a427010846d683e4aed6 Mon Sep 17 00:00:00 2001 From: xiang <308260887@qq.com> Date: Wed, 21 Jun 2023 17:44:37 +0800 Subject: [PATCH 6/9] Update eip-8888.md --- EIPS/eip-8888.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-8888.md b/EIPS/eip-8888.md index 0fa31be3338d9..1fb0679a2d6c8 100644 --- a/EIPS/eip-8888.md +++ b/EIPS/eip-8888.md @@ -19,7 +19,7 @@ A proposal to manage fungible tokens by the user's smart contract wallet, which EOA wallet has no state and code storage, and the smart contract wallet is different. -AA is a direction of the smart contract wallet, which works around abstract accounts. This EIP can also be an extension based on [EIP-4337](./eip-4337.md). +AA is a direction of the smart contract wallet, which works around abstract accounts. This EIP can also be an extension based on [ERC-4337](./eip-4337.md). The smart contract wallet allows the user's own account to have state and code, bringing programmability to the wallet. We think there are more directions to expand. For example, token asset management, functional expansion of token transactions, etc. @@ -210,7 +210,7 @@ sequenceDiagram ## Backwards Compatibility -This EIP can be used as an extension of EIP-4337 and is backward compatible with EIP-4337. +This EIP can be used as an extension of [ERC-4337](./eip-4337.md) and is backward compatible with ERC-4337. ## Reference Implementation From 3cca663c35a6174b8b6ba6d933348d544e4652a6 Mon Sep 17 00:00:00 2001 From: xiang <308260887@qq.com> Date: Fri, 23 Jun 2023 00:49:53 +0800 Subject: [PATCH 7/9] Update and rename eip-8888.md to eip-7204.md --- EIPS/{eip-8888.md => eip-7204.md} | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) rename EIPS/{eip-8888.md => eip-7204.md} (92%) diff --git a/EIPS/eip-8888.md b/EIPS/eip-7204.md similarity index 92% rename from EIPS/eip-8888.md rename to EIPS/eip-7204.md index 1fb0679a2d6c8..ee0e05fb52d95 100644 --- a/EIPS/eip-8888.md +++ b/EIPS/eip-7204.md @@ -1,5 +1,5 @@ --- -eip: 8888 +eip: 7204 title: contract wallet management asset description: fungible tokens author: Xiang (@wenzhenxiang), Ben77 (@ben2077), Mingshi S. (@newnewsms) @@ -23,7 +23,7 @@ AA is a direction of the smart contract wallet, which works around abstract acco The smart contract wallet allows the user's own account to have state and code, bringing programmability to the wallet. We think there are more directions to expand. For example, token asset management, functional expansion of token transactions, etc. -The smart contract wallet interface of this EIP is for asset management and asset approval. It supports the new asset EIP-X, and [ERC-20](./eip-20.md) is backward compatible with EIP-X, so it can be compatible with the management of all fungible tokens in the existing market. +The smart contract wallet interface of this EIP is for asset management and asset approval. It supports the new asset EIP-7196, and [ERC-20](./eip-20.md) is backward compatible with EIP-7196, so it can be compatible with the management of all fungible tokens in the existing market. The proposal aims to achieve the following goals: @@ -37,15 +37,15 @@ The proposal aims to achieve the following goals: The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -**Every ERC-Y compliant contract must implement the ERC-Y and [ERC-165](./eip-165) interfaces** +**Every ERC-7204 compliant contract must implement the ERC-7204 and [ERC-165](./eip-165) interfaces** ```solidity -/// @title ERC-Y -/// @dev See https://eips.ethereum.org/EIPS/eip-Y +/// @title ERC-7204 +/// @dev See https://eips.ethereum.org/EIPS/eip-7204 /// @dev Note: the ERC-165 identifier for this interface is 0xf73edcda pragma solidity ^0.8.20; -interface IERCY /* is ERC165 */ { +interface IERC7204 /* is ERC165 */ { /** * @notice Used to notify listeners that owner has granted approval to the user to manage assets tokens. @@ -106,13 +106,13 @@ interface IERCY /* is ERC165 */ { Batch operation extension is OPTIONAL, here allows batch transfer and batch approve. Smart contracts MUST implement the ERC-165 supportsInterface function. ```solidity -/// @title ERC-YBatch -/// @dev See https://eips.ethereum.org/EIPS/eip-Y +/// @title ERC-7204Batch +/// @dev See https://eips.ethereum.org/EIPS/eip-7204 /// @dev Note: the ERC-165 identifier for this interface is 0xaae6c42c pragma solidity ^0.8.20; -interface IERCYBatch /* is ERC165 */ { +interface IERC7204Batch /* is ERC165 */ { /** * @notice Batch approve fungible token @@ -215,18 +215,18 @@ This EIP can be used as an extension of [ERC-4337](./eip-4337.md) and is backwar ## Reference Implementation ```solidity -contract ERCY is IERCY,IERCYBatch,ERC165{ +contract ERC7204 is IERC7204,IERC7204Batch,ERC165{ mapping (address => mapping (address => uint256)) private _allowances; bytes4 constant private INTERFACE_SIGNATURE_ERC165 = 0x01ffc9a7; - bytes4 constant private INTERFACE_SIGNATURE_ERCY = 0xf73edcda; - bytes4 constant private INTERFACE_SIGNATURE_ERCYBATCH = 0xaae6c42c; + bytes4 constant private INTERFACE_SIGNATURE_ERC7204 = 0xf73edcda; + bytes4 constant private INTERFACE_SIGNATURE_ERC7204BATCH = 0xaae6c42c; function supportsInterface(bytes4 _interfaceId) public pure returns (bool) { if (_interfaceId == INTERFACE_SIGNATURE_ERC165 || - _interfaceId == INTERFACE_SIGNATURE_ERCY || - _interfaceId == INTERFACE_SIGNATURE_ERCYBATCH) { + _interfaceId == INTERFACE_SIGNATURE_ERC7204 || + _interfaceId == INTERFACE_SIGNATURE_ERC7204BATCH) { return true; } return false; From 332af8efaf38f9aead91a834885c7f83d18a1afe Mon Sep 17 00:00:00 2001 From: xiang <308260887@qq.com> Date: Fri, 23 Jun 2023 00:56:04 +0800 Subject: [PATCH 8/9] Update eip-7204.md --- EIPS/eip-7204.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7204.md b/EIPS/eip-7204.md index ee0e05fb52d95..d688fc2fce667 100644 --- a/EIPS/eip-7204.md +++ b/EIPS/eip-7204.md @@ -23,7 +23,7 @@ AA is a direction of the smart contract wallet, which works around abstract acco The smart contract wallet allows the user's own account to have state and code, bringing programmability to the wallet. We think there are more directions to expand. For example, token asset management, functional expansion of token transactions, etc. -The smart contract wallet interface of this EIP is for asset management and asset approval. It supports the new asset EIP-7196, and [ERC-20](./eip-20.md) is backward compatible with EIP-7196, so it can be compatible with the management of all fungible tokens in the existing market. +The smart contract wallet interface of this EIP is for asset management and asset approval. It supports the new asset EIP-X, and [ERC-20](./eip-20.md) is backward compatible with EIP-X, so it can be compatible with the management of all fungible tokens in the existing market. The proposal aims to achieve the following goals: @@ -37,7 +37,7 @@ The proposal aims to achieve the following goals: The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -**Every ERC-7204 compliant contract must implement the ERC-7204 and [ERC-165](./eip-165) interfaces** +**Every [ERC-7204]((./eip-7204)) compliant contract must implement the ERC-7204 and [ERC-165](./eip-165) interfaces** ```solidity /// @title ERC-7204 From 482fa0f81ab72749546bf0f294f539312ab1f180 Mon Sep 17 00:00:00 2001 From: xiang <308260887@qq.com> Date: Fri, 23 Jun 2023 01:59:22 +0800 Subject: [PATCH 9/9] Update eip-7204.md --- EIPS/eip-7204.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7204.md b/EIPS/eip-7204.md index d688fc2fce667..39ce7664733b1 100644 --- a/EIPS/eip-7204.md +++ b/EIPS/eip-7204.md @@ -37,7 +37,7 @@ The proposal aims to achieve the following goals: The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -**Every [ERC-7204]((./eip-7204)) compliant contract must implement the ERC-7204 and [ERC-165](./eip-165) interfaces** +** Compliant contract must implement the [ERC-165](./eip-165) interfaces** ```solidity /// @title ERC-7204