diff --git a/.github/workflows/build-lint-test.yml b/.github/workflows/build-lint-test.yml
index 99b5a8e54..d5cf13392 100644
--- a/.github/workflows/build-lint-test.yml
+++ b/.github/workflows/build-lint-test.yml
@@ -64,7 +64,6 @@ jobs:
"upinit",
"lsp1",
"lsp2",
- "lsp4",
"lsp6",
"lsp6init",
"lsp7",
diff --git a/constants.ts b/constants.ts
index 18c3aaebf..c7802d7a8 100644
--- a/constants.ts
+++ b/constants.ts
@@ -17,6 +17,7 @@ export const INTERFACE_IDS = {
ERC165: '0x01ffc9a7',
ERC1271: '0x1626ba7e',
ERC20: '0x36372b07',
+ ERC20Metadata: '0xa219a025',
ERC223: '0x87d43052',
ERC721: '0x80ac58cd',
ERC721Metadata: '0x5b5e139f',
diff --git a/contracts/LSP4DigitalAssetMetadata/ILSP4Compatibility.sol b/contracts/LSP4DigitalAssetMetadata/ILSP4Compatibility.sol
deleted file mode 100644
index ede2d60a7..000000000
--- a/contracts/LSP4DigitalAssetMetadata/ILSP4Compatibility.sol
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-pragma solidity ^0.8.4;
-
-// interfaces
-import {
- IERC725Y
-} from "@erc725/smart-contracts/contracts/interfaces/IERC725Y.sol";
-
-/**
- * @dev LSP4 extension, for compatibility with clients & tools that expect ERC20/721.
- */
-interface ILSP4Compatibility is IERC725Y {
- /**
- * @dev Returns the name of the token.
- * @return The name of the token
- */
- function name() external view returns (string memory);
-
- /**
- * @dev Returns the symbol of the token, usually a shorter version of the name.
- * @return The symbol of the token
- */
- function symbol() external view returns (string memory);
-}
diff --git a/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol b/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol
deleted file mode 100644
index fe661e18e..000000000
--- a/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-pragma solidity ^0.8.4;
-
-// interfaces
-import {ILSP4Compatibility} from "./ILSP4Compatibility.sol";
-
-// modules
-import {ERC725YCore} from "@erc725/smart-contracts/contracts/ERC725YCore.sol";
-
-// constants
-import {
- _LSP4_TOKEN_NAME_KEY,
- _LSP4_TOKEN_SYMBOL_KEY
-} from "./LSP4Constants.sol";
-
-/**
- * @title LSP4Compatibility
- * @author Matthew Stevens
- * @dev LSP4 extension, for compatibility with clients & tools that expect ERC20/721.
- */
-abstract contract LSP4Compatibility is ILSP4Compatibility, ERC725YCore {
- // --- Token queries
-
- /**
- * @dev Returns the name of the token.
- * @return The name of the token
- */
- function name() public view virtual override returns (string memory) {
- bytes memory data = _getData(_LSP4_TOKEN_NAME_KEY);
- return string(data);
- }
-
- /**
- * @dev Returns the symbol of the token, usually a shorter version of the name.
- * @return The symbol of the token
- */
- function symbol() public view virtual override returns (string memory) {
- bytes memory data = _getData(_LSP4_TOKEN_SYMBOL_KEY);
- return string(data);
- }
-}
diff --git a/contracts/LSP7DigitalAsset/extensions/ILSP7CompatibleERC20.sol b/contracts/LSP7DigitalAsset/extensions/ILSP7CompatibleERC20.sol
deleted file mode 100644
index 38cdb68c6..000000000
--- a/contracts/LSP7DigitalAsset/extensions/ILSP7CompatibleERC20.sol
+++ /dev/null
@@ -1,83 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-pragma solidity ^0.8.4;
-
-// interfaces
-import {ILSP7DigitalAsset} from "../ILSP7DigitalAsset.sol";
-
-/**
- * @dev LSP7 extension, for compatibility for clients / tools that expect ERC20.
- */
-interface ILSP7CompatibleERC20 is ILSP7DigitalAsset {
- /**
- * @dev ERC20 `Transfer` event emitted when `amount` tokens is transferred from `from` to `to`.
- * To provide compatibility with indexing ERC20 events.
- *
- * @param from The sending address
- * @param to The receiving address
- * @param value The amount of tokens transfered.
- */
- event Transfer(address indexed from, address indexed to, uint256 value);
-
- /**
- * @dev ERC20 `Approval` event emitted when `owner` enables `spender` for `value` tokens.
- * To provide compatibility with indexing ERC20 events.
- *
- * @param owner The account giving approval
- * @param spender The account receiving approval
- * @param value The amount of tokens `spender` has access to from `owner`
- */
- event Approval(
- address indexed owner,
- address indexed spender,
- uint256 value
- );
-
- /*
- * @dev Transfer function from the ERC20 standard interface.
-
- * @param to The address receiving tokens.
- * @param amount The amount of tokens to transfer.
- *
- * @return `true` on successful transfer.
- */
- function transfer(address to, uint256 amount) external returns (bool);
-
- /*
- * @dev Transfer functions for operators from the ERC20 standard interface.
-
- * @param from The address sending tokens.
- * @param to The address receiving tokens.
- * @param amount The amount of tokens to transfer.
- *
- * @return `true` on successful transfer.
- */
- function transferFrom(
- address from,
- address to,
- uint256 amount
- ) external returns (bool);
-
- /*
- * @dev Approval function from th ERC20 standard interface.
-
- * @param operator The address to approve for `amount`
- * @param amount The amount to approve.
- *
- * @return `true` on successful approval.
- */
- function approve(address operator, uint256 amount) external returns (bool);
-
- /*
- * @dev Function to get operator allowance allowed to spend on behalf of `tokenOwner` from the ERC20 standard interface.
-
- * @param tokenOwner The address of the token owner
- * @param operator The address approved by the `tokenOwner`
- *
- * @return The amount `operator` is approved by `tokenOwner`
- */
- function allowance(
- address tokenOwner,
- address operator
- ) external view returns (uint256);
-}
diff --git a/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol b/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol
index b9b0e473e..bc7cfa546 100644
--- a/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol
+++ b/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol
@@ -1,28 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
-pragma solidity ^0.8.12;
+pragma solidity ^0.8.7;
// interfaces
-import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-import {ILSP7CompatibleERC20} from "./ILSP7CompatibleERC20.sol";
+import {
+ IERC20Metadata,
+ IERC20
+} from "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";
// modules
+import {LSP7DigitalAssetCore, LSP7DigitalAsset} from "../LSP7DigitalAsset.sol";
+
+// constants
import {
- LSP4Compatibility
-} from "../../LSP4DigitalAssetMetadata/LSP4Compatibility.sol";
-import {
- LSP7DigitalAsset,
- LSP4DigitalAssetMetadata,
- ERC725YCore
-} from "../LSP7DigitalAsset.sol";
+ _LSP4_TOKEN_NAME_KEY,
+ _LSP4_TOKEN_SYMBOL_KEY
+} from "../../LSP4DigitalAssetMetadata/LSP4Constants.sol";
/**
* @dev LSP7 extension, for compatibility for clients / tools that expect ERC20.
*/
-abstract contract LSP7CompatibleERC20 is
- ILSP7CompatibleERC20,
- LSP4Compatibility,
- LSP7DigitalAsset
-{
+abstract contract LSP7CompatibleERC20 is IERC20Metadata, LSP7DigitalAsset {
/**
* @notice Deploying a `LSP7CompatibleERC20` token contract with: token name = `name_`, token symbol = `symbol_`, and
* address `newOwner_` as the token contract owner.
@@ -38,22 +35,90 @@ abstract contract LSP7CompatibleERC20 is
) LSP7DigitalAsset(name_, symbol_, newOwner_, false) {}
/**
- * @inheritdoc LSP7DigitalAsset
+ * @inheritdoc IERC20Metadata
+ * @dev Returns the name of the token.
+ * For compatibility with clients & tools that expect ERC20.
+ *
+ * @return The name of the token
*/
- function supportsInterface(
- bytes4 interfaceId
+ function name() public view virtual override returns (string memory) {
+ bytes memory data = _getData(_LSP4_TOKEN_NAME_KEY);
+ return string(data);
+ }
+
+ /**
+ * @inheritdoc IERC20Metadata
+ * @dev Returns the symbol of the token, usually a shorter version of the name.
+ * For compatibility with clients & tools that expect ERC20.
+ *
+ * @return The symbol of the token
+ */
+ function symbol() public view virtual override returns (string memory) {
+ bytes memory data = _getData(_LSP4_TOKEN_SYMBOL_KEY);
+ return string(data);
+ }
+
+ /**
+ * @inheritdoc LSP7DigitalAssetCore
+ */
+ function decimals()
+ public
+ view
+ virtual
+ override(IERC20Metadata, LSP7DigitalAssetCore)
+ returns (uint8)
+ {
+ return super.decimals();
+ }
+
+ /**
+ * @inheritdoc LSP7DigitalAssetCore
+ */
+ function totalSupply()
+ public
+ view
+ virtual
+ override(IERC20, LSP7DigitalAssetCore)
+ returns (uint256)
+ {
+ return super.totalSupply();
+ }
+
+ /**
+ * @inheritdoc LSP7DigitalAssetCore
+ */
+ function balanceOf(
+ address tokenOwner
)
public
view
virtual
- override(IERC165, ERC725YCore, LSP7DigitalAsset)
- returns (bool)
+ override(IERC20, LSP7DigitalAssetCore)
+ returns (uint256)
{
- return super.supportsInterface(interfaceId);
+ return super.balanceOf(tokenOwner);
+ }
+
+ /**
+ * @inheritdoc LSP7DigitalAsset
+ */
+ function supportsInterface(
+ bytes4 interfaceId
+ ) public view virtual override returns (bool) {
+ return
+ interfaceId == type(IERC20).interfaceId ||
+ interfaceId == type(IERC20Metadata).interfaceId ||
+ super.supportsInterface(interfaceId);
}
/**
- * @inheritdoc ILSP7CompatibleERC20
+ * @inheritdoc IERC20
+ * @dev Function to get operator allowance allowed to spend on behalf of `tokenOwner` from the ERC20 standard interface.
+ *
+ * @param tokenOwner The address of the token owner
+ * @param operator The address approved by the `tokenOwner`
+ *
+ * @return The amount `operator` is approved by `tokenOwner`
*/
function allowance(
address tokenOwner,
@@ -63,7 +128,13 @@ abstract contract LSP7CompatibleERC20 is
}
/**
- * @inheritdoc ILSP7CompatibleERC20
+ * @inheritdoc IERC20
+ * @dev Approval function from th ERC20 standard interface.
+ *
+ * @param operator The address to approve for `amount`
+ * @param amount The amount to approve.
+ *
+ * @return `true` on successful approval.
*/
function approve(
address operator,
@@ -74,7 +145,14 @@ abstract contract LSP7CompatibleERC20 is
}
/**
- * @inheritdoc ILSP7CompatibleERC20
+ * @inheritdoc IERC20
+ * @dev Transfer functions for operators from the ERC20 standard interface.
+ *
+ * @param from The address sending tokens.
+ * @param to The address receiving tokens.
+ * @param amount The amount of tokens to transfer.
+ *
+ * @return `true` on successful transfer.
*
* @custom:info This function uses the `force` parameter as `true` so that EOA and any contract can receive tokens.
*/
@@ -90,7 +168,13 @@ abstract contract LSP7CompatibleERC20 is
// --- Overrides
/**
- * @inheritdoc ILSP7CompatibleERC20
+ * @inheritdoc IERC20
+ * @dev Transfer function from the ERC20 standard interface.
+
+ * @param to The address receiving tokens.
+ * @param amount The amount of tokens to transfer.
+ *
+ * @return `true` on successful transfer.
*
* @custom:info This function uses the `force` parameter as `true` so that EOA and any contract can receive tokens.
*/
@@ -102,6 +186,9 @@ abstract contract LSP7CompatibleERC20 is
return true;
}
+ /**
+ * @inheritdoc LSP7DigitalAssetCore
+ */
function _updateOperator(
address tokenOwner,
address operator,
@@ -114,7 +201,7 @@ abstract contract LSP7CompatibleERC20 is
amount,
operatorNotificationData
);
- emit Approval(tokenOwner, operator, amount);
+ emit IERC20.Approval(tokenOwner, operator, amount);
}
/**
@@ -129,7 +216,7 @@ abstract contract LSP7CompatibleERC20 is
bool force,
bytes memory data
) internal virtual override {
- emit Transfer(from, to, amount);
+ emit IERC20.Transfer(from, to, amount);
super._transfer(from, to, amount, force, data);
}
@@ -144,7 +231,7 @@ abstract contract LSP7CompatibleERC20 is
bool force,
bytes memory data
) internal virtual override {
- emit Transfer(address(0), to, amount);
+ emit IERC20.Transfer(address(0), to, amount);
super._mint(to, amount, force, data);
}
@@ -158,17 +245,7 @@ abstract contract LSP7CompatibleERC20 is
uint256 amount,
bytes memory data
) internal virtual override {
- emit Transfer(from, address(0), amount);
+ emit IERC20.Transfer(from, address(0), amount);
super._burn(from, amount, data);
}
-
- /**
- * @inheritdoc LSP4DigitalAssetMetadata
- */
- function _setData(
- bytes32 key,
- bytes memory value
- ) internal virtual override(LSP4DigitalAssetMetadata, ERC725YCore) {
- super._setData(key, value);
- }
}
diff --git a/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol b/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol
index 4b64a16d3..840e537ed 100644
--- a/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol
+++ b/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol
@@ -1,26 +1,29 @@
// SPDX-License-Identifier: Apache-2.0
-pragma solidity ^0.8.12;
+pragma solidity ^0.8.7;
// interfaces
-import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-import {ILSP7CompatibleERC20} from "./ILSP7CompatibleERC20.sol";
+import {
+ IERC20Metadata,
+ IERC20
+} from "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";
// modules
import {
- LSP4Compatibility
-} from "../../LSP4DigitalAssetMetadata/LSP4Compatibility.sol";
-import {
- LSP7DigitalAssetInitAbstract,
- LSP4DigitalAssetMetadataInitAbstract,
- ERC725YCore
+ LSP7DigitalAssetCore,
+ LSP7DigitalAssetInitAbstract
} from "../LSP7DigitalAssetInitAbstract.sol";
+// constants
+import {
+ _LSP4_TOKEN_NAME_KEY,
+ _LSP4_TOKEN_SYMBOL_KEY
+} from "../../LSP4DigitalAssetMetadata/LSP4Constants.sol";
+
/**
* @dev LSP7 extension, for compatibility for clients / tools that expect ERC20.
*/
abstract contract LSP7CompatibleERC20InitAbstract is
- ILSP7CompatibleERC20,
- LSP4Compatibility,
+ IERC20Metadata,
LSP7DigitalAssetInitAbstract
{
/**
@@ -45,32 +48,106 @@ abstract contract LSP7CompatibleERC20InitAbstract is
}
/**
- * @inheritdoc LSP7DigitalAssetInitAbstract
+ * @inheritdoc IERC20Metadata
+ * @dev Returns the name of the token.
+ * For compatibility with clients & tools that expect ERC20.
+ *
+ * @return The name of the token
*/
- function supportsInterface(
- bytes4 interfaceId
+ function name() public view virtual override returns (string memory) {
+ bytes memory data = _getData(_LSP4_TOKEN_NAME_KEY);
+ return string(data);
+ }
+
+ /**
+ * @inheritdoc IERC20Metadata
+ * @dev Returns the symbol of the token, usually a shorter version of the name.
+ * For compatibility with clients & tools that expect ERC20.
+ *
+ * @return The symbol of the token
+ */
+ function symbol() public view virtual override returns (string memory) {
+ bytes memory data = _getData(_LSP4_TOKEN_SYMBOL_KEY);
+ return string(data);
+ }
+
+ /**
+ * @inheritdoc LSP7DigitalAssetCore
+ */
+ function decimals()
+ public
+ view
+ virtual
+ override(IERC20Metadata, LSP7DigitalAssetCore)
+ returns (uint8)
+ {
+ return super.decimals();
+ }
+
+ /**
+ * @inheritdoc LSP7DigitalAssetCore
+ */
+ function totalSupply()
+ public
+ view
+ virtual
+ override(IERC20, LSP7DigitalAssetCore)
+ returns (uint256)
+ {
+ return super.totalSupply();
+ }
+
+ /**
+ * @inheritdoc LSP7DigitalAssetCore
+ */
+ function balanceOf(
+ address tokenOwner
)
public
view
virtual
- override(IERC165, ERC725YCore, LSP7DigitalAssetInitAbstract)
- returns (bool)
+ override(IERC20, LSP7DigitalAssetCore)
+ returns (uint256)
{
- return super.supportsInterface(interfaceId);
+ return super.balanceOf(tokenOwner);
}
/**
- * @inheritdoc ILSP7CompatibleERC20
+ * @inheritdoc LSP7DigitalAssetInitAbstract
+ */
+ function supportsInterface(
+ bytes4 interfaceId
+ ) public view virtual override returns (bool) {
+ return
+ interfaceId == type(IERC20).interfaceId ||
+ interfaceId == type(IERC20Metadata).interfaceId ||
+ super.supportsInterface(interfaceId);
+ }
+
+ /**
+ * @inheritdoc IERC20
+ * @dev Function to get operator allowance allowed to spend on behalf of `tokenOwner` from the ERC20 standard interface.
+ *
+ * @param tokenOwner The address of the token owner
+ * @param operator The address approved by the `tokenOwner`
+ *
+ * @return The amount `operator` is approved by `tokenOwner`
*/
function allowance(
address tokenOwner,
address operator
- ) public view virtual returns (uint256) {
+ ) public view virtual override returns (uint256) {
return authorizedAmountFor(operator, tokenOwner);
}
/**
- * @inheritdoc ILSP7CompatibleERC20
+ * @inheritdoc IERC20
+ * @dev Approval function from th ERC20 standard interface.
+ *
+ * @param operator The address to approve for `amount`
+ * @param amount The amount to approve.
+ *
+ * @return `true` on successful approval.
*/
function approve(
address operator,
@@ -81,7 +158,14 @@ abstract contract LSP7CompatibleERC20InitAbstract is
}
/**
- * @inheritdoc ILSP7CompatibleERC20
+ * @inheritdoc IERC20
+ * @dev Transfer functions for operators from the ERC20 standard interface.
+ *
+ * @param from The address sending tokens.
+ * @param to The address receiving tokens.
+ * @param amount The amount of tokens to transfer.
+ *
+ * @return `true` on successful transfer.
*
* @custom:info This function uses the `force` parameter as `true` so that EOA and any contract can receive tokens.
*/
@@ -97,7 +181,13 @@ abstract contract LSP7CompatibleERC20InitAbstract is
// --- Overrides
/**
- * @inheritdoc ILSP7CompatibleERC20
+ * @inheritdoc IERC20
+ * @dev Transfer function from the ERC20 standard interface.
+ *
+ * @param to The address receiving tokens.
+ * @param amount The amount of tokens to transfer.
+ *
+ * @return `true` on successful transfer.
*
* @custom:info This function uses the `force` parameter as `true` so that EOA and any contract can receive tokens.
*/
@@ -109,6 +199,9 @@ abstract contract LSP7CompatibleERC20InitAbstract is
return true;
}
+ /**
+ * @inheritdoc LSP7DigitalAssetCore
+ */
function _updateOperator(
address tokenOwner,
address operator,
@@ -121,7 +214,7 @@ abstract contract LSP7CompatibleERC20InitAbstract is
amount,
operatorNotificationData
);
- emit Approval(tokenOwner, operator, amount);
+ emit IERC20.Approval(tokenOwner, operator, amount);
}
/**
@@ -136,7 +229,7 @@ abstract contract LSP7CompatibleERC20InitAbstract is
bool force,
bytes memory data
) internal virtual override {
- emit Transfer(from, to, amount);
+ emit IERC20.Transfer(from, to, amount);
super._transfer(from, to, amount, force, data);
}
@@ -151,7 +244,7 @@ abstract contract LSP7CompatibleERC20InitAbstract is
bool force,
bytes memory data
) internal virtual override {
- emit Transfer(address(0), to, amount);
+ emit IERC20.Transfer(address(0), to, amount);
super._mint(to, amount, force, data);
}
@@ -165,21 +258,7 @@ abstract contract LSP7CompatibleERC20InitAbstract is
uint256 amount,
bytes memory data
) internal virtual override {
- emit Transfer(from, address(0), amount);
+ emit IERC20.Transfer(from, address(0), amount);
super._burn(from, amount, data);
}
-
- /**
- * @inheritdoc LSP4DigitalAssetMetadataInitAbstract
- */
- function _setData(
- bytes32 key,
- bytes memory value
- )
- internal
- virtual
- override(LSP4DigitalAssetMetadataInitAbstract, ERC725YCore)
- {
- super._setData(key, value);
- }
}
diff --git a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol b/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol
index 4595ed749..c3833e16e 100644
--- a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol
+++ b/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
-pragma solidity ^0.8.12;
+pragma solidity ^0.8.7;
import {LSP7CompatibleERC20} from "../extensions/LSP7CompatibleERC20.sol";
diff --git a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInit.sol b/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInit.sol
index f75b4b758..83ace62b5 100644
--- a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInit.sol
+++ b/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInit.sol
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
-pragma solidity ^0.8.12;
+pragma solidity ^0.8.7;
// modules
import {
diff --git a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInitAbstract.sol b/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInitAbstract.sol
index 95b0bee2c..9b831d11a 100644
--- a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInitAbstract.sol
+++ b/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInitAbstract.sol
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
-pragma solidity ^0.8.12;
+pragma solidity ^0.8.7;
// modules
import {
diff --git a/contracts/LSP8IdentifiableDigitalAsset/extensions/ILSP8CompatibleERC721.sol b/contracts/LSP8IdentifiableDigitalAsset/extensions/ILSP8CompatibleERC721.sol
deleted file mode 100644
index 6548fee57..000000000
--- a/contracts/LSP8IdentifiableDigitalAsset/extensions/ILSP8CompatibleERC721.sol
+++ /dev/null
@@ -1,175 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-pragma solidity ^0.8.4;
-
-// interfaces
-import {
- ILSP8IdentifiableDigitalAsset
-} from "../ILSP8IdentifiableDigitalAsset.sol";
-
-// --- ERC165 interface ids
-bytes4 constant _INTERFACEID_ERC721 = 0x80ac58cd;
-bytes4 constant _INTERFACEID_ERC721METADATA = 0x5b5e139f;
-
-/**
- * @dev LSP8 extension, for compatibility for clients / tools that expect ERC721.
- */
-interface ILSP8CompatibleERC721 is ILSP8IdentifiableDigitalAsset {
- /**
- * @notice ERC721 `Transfer` compatible event emitted. Successfully transferred tokenId `tokenId` from `from` to `to`.
- *
- * @dev ERC721 `Transfer` event emitted when `tokenId` token is transferred from `from` to `to`.
- * To provide compatibility with indexing ERC721 events.
- *
- * @param from The sending address.
- * @param to The receiving address.
- * @param tokenId The tokenId to transfer.
- */
- event Transfer(
- address indexed from,
- address indexed to,
- uint256 indexed tokenId
- );
-
- /**
- * @notice ERC721 `Approval` compatible event emitted. Successfully approved operator `operator` to operate on tokenId `tokenId` on behalf of token owner `owner`.
- *
- * @dev ERC721 `Approval` event emitted when `owner` enables `operator` for `tokenId`.
- * To provide compatibility with indexing ERC721 events.
- *
- * @param owner The address of the owner of the `tokenId`.
- * @param operator The address set as operator.
- * @param tokenId The approved tokenId.
- */
- event Approval(
- address indexed owner,
- address indexed operator,
- uint256 indexed tokenId
- );
-
- /**
- * @notice ERC721 `ApprovalForAll` compatible event emitted. Successfully set "approved for all" status to `approved` for operator `operator` for token owner `owner`.
- *
- * @dev ERC721 `ApprovalForAll` event emitted when an `operator` is enabled or disabled for an owner
- * to transfer any of its tokenIds. The operator can manage all NFTs of the owner.
- *
- * @param owner The address of the owner of tokenIds.
- * @param operator The address set as operator.
- * @param approved If `operator` is approved for all NFTs or not.
- */
- event ApprovalForAll(
- address indexed owner,
- address indexed operator,
- bool approved
- );
-
- /**
- * @notice Calling `transferFrom` function on `ILSP8CompatibleERC721` contract. Transferring tokenId `tokenId` from address `from` to address `to`.
- *
- * @dev Transfer functions from the ERC721 standard interface.
- *
- * @param from The sending address.
- * @param to The receiving address.
- * @param tokenId The tokenId to transfer.
- */
- function transferFrom(address from, address to, uint256 tokenId) external;
-
- /**
- * @notice Calling `safeTransferFrom` function on `ILSP8CompatibleERC721` contract. Transferring tokenId `tokenId` from address `from` to address `to`.
- *
- * @dev Safe Transfer function without optional data from the ERC721 standard interface.
- *
- * @param from The sending address.
- * @param to The receiving address.
- * @param tokenId The tokenId to transfer.
- */
- function safeTransferFrom(
- address from,
- address to,
- uint256 tokenId
- ) external;
-
- /**
- * @notice Calling `safeTransferFrom` function with `data` on `ILSP8CompatibleERC721` contract. Transferring tokenId `tokenId` from address `from` to address `to`.
- *
- * @dev Safe Transfer function with optional data from the ERC721 standard interface.
- *
- * @param from The sending address.
- * @param to The receiving address.
- * @param tokenId The tokenId to transfer.
- * @param data The data to be sent with the transfer.
- */
- function safeTransferFrom(
- address from,
- address to,
- uint256 tokenId,
- bytes memory data
- ) external;
-
- /**
- * @notice Retrieving the address that own tokenId `tokenId`.
- *
- * @dev Compatible with ERC721 ownerOf.
- *
- * @param tokenId The tokenId to query.
- * @return The owner of the tokenId.
- */
- function ownerOf(uint256 tokenId) external view returns (address);
-
- /**
- * @notice Calling `approve` function on `ILSP8CompatibleERC721` contract. Approving operator at address `operator` to transfer tokenId `tokenId` on behalf of its owner.
- *
- * @dev Approval function compatible with ERC721 `approve(address,uint256)`.
- *
- * @param operator The address to approve for `tokenId`.
- * @param tokenId The tokenId to approve.
- */
- function approve(address operator, uint256 tokenId) external;
-
- /**
- * @notice Setting the "approval for all" status of operator `_operator` to `_approved` to allow it to transfer any tokenIds on behalf of `msg.sender`.
- *
- * @dev Enable or disable approval for a third party ("operator") to manage all of `msg.sender`'s assets. The contract MUST allow multiple operators per owner.
- *
- * @param _operator Address to add to the set of authorized operators.
- * @param _approved True if the operator is approved, false to revoke approval.
- *
- * @custom:events {ApprovalForAll} event
- */
- function setApprovalForAll(address _operator, bool _approved) external;
-
- /**
- * @notice Retrieving the address other than the token owner that is approved to transfer tokenId `tokenId` on behalf of its owner.
- *
- * @dev Compatible with ERC721 getApproved.
- *
- * @param tokenId The tokenId to query.
- * @return The address of the operator for `tokenId`.
- */
- function getApproved(uint256 tokenId) external view returns (address);
-
- /*
- * @notice Checking if address `operator` is approved to transfer any tokenId owned by address `owner`.
- *
- * @dev Compatible with ERC721 isApprovedForAll.
- *
- * @param owner The tokenOwner address to query.
- * @param operator The operator address to query.
- *
- * @return Returns if the `operator` is allowed to manage all of the assets of `owner`
- */
- function isApprovedForAll(
- address owner,
- address operator
- ) external view returns (bool);
-
- /*
- * @notice Retrieving the token URI of tokenId `tokenId`.
- *
- * @dev Compatible with ERC721Metadata tokenURI.
- *
- * @param tokenId The tokenId to query.
- *
- * @return The token URI.
- */
- function tokenURI(uint256 tokenId) external returns (string memory);
-}
diff --git a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol b/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol
index 6136f4cf1..0363756f3 100644
--- a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol
+++ b/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol
@@ -5,11 +5,11 @@ pragma solidity ^0.8.12;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {
IERC721Receiver
-} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
-import {ILSP8CompatibleERC721} from "./ILSP8CompatibleERC721.sol";
+} from "@openzeppelin/contracts/interfaces/IERC721Receiver.sol";
import {
- ILSP8IdentifiableDigitalAsset
-} from "../ILSP8IdentifiableDigitalAsset.sol";
+ IERC721Metadata,
+ IERC721
+} from "@openzeppelin/contracts/interfaces/IERC721Metadata.sol";
// libraries
import {
@@ -19,15 +19,9 @@ import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";
// modules
import {
- LSP4Compatibility
-} from "../../LSP4DigitalAssetMetadata/LSP4Compatibility.sol";
-import {
- LSP8IdentifiableDigitalAsset,
- ERC725YCore
+ LSP8IdentifiableDigitalAssetCore,
+ LSP8IdentifiableDigitalAsset
} from "../LSP8IdentifiableDigitalAsset.sol";
-import {
- LSP8IdentifiableDigitalAssetCore
-} from "../LSP8IdentifiableDigitalAssetCore.sol";
// errors
import {
@@ -40,19 +34,16 @@ import {
// constants
import {
- _LSP4_METADATA_KEY
+ _LSP4_METADATA_KEY,
+ _LSP4_TOKEN_NAME_KEY,
+ _LSP4_TOKEN_SYMBOL_KEY
} from "../../LSP4DigitalAssetMetadata/LSP4Constants.sol";
-import {
- _INTERFACEID_ERC721,
- _INTERFACEID_ERC721METADATA
-} from "././ILSP8CompatibleERC721.sol";
/**
* @dev LSP8 extension, for compatibility for clients / tools that expect ERC721.
*/
abstract contract LSP8CompatibleERC721 is
- ILSP8CompatibleERC721,
- LSP4Compatibility,
+ IERC721Metadata,
LSP8IdentifiableDigitalAsset
{
using EnumerableSet for EnumerableSet.AddressSet;
@@ -77,6 +68,45 @@ abstract contract LSP8CompatibleERC721 is
uint256 tokenIdType_
) LSP8IdentifiableDigitalAsset(name_, symbol_, newOwner_, tokenIdType_) {}
+ /**
+ * @inheritdoc IERC721Metadata
+ * @dev Returns the name of the token.
+ * For compatibility with clients & tools that expect ERC721.
+ *
+ * @return The name of the token
+ */
+ function name() public view virtual override returns (string memory) {
+ bytes memory data = _getData(_LSP4_TOKEN_NAME_KEY);
+ return string(data);
+ }
+
+ /**
+ * @inheritdoc IERC721Metadata
+ * @dev Returns the symbol of the token, usually a shorter version of the name.
+ * For compatibility with clients & tools that expect ERC721.
+ *
+ * @return The symbol of the token
+ */
+ function symbol() public view virtual override returns (string memory) {
+ bytes memory data = _getData(_LSP4_TOKEN_SYMBOL_KEY);
+ return string(data);
+ }
+
+ /**
+ * @inheritdoc LSP8IdentifiableDigitalAssetCore
+ */
+ function balanceOf(
+ address tokenOwner
+ )
+ public
+ view
+ virtual
+ override(IERC721, LSP8IdentifiableDigitalAssetCore)
+ returns (uint256)
+ {
+ return super.balanceOf(tokenOwner);
+ }
+
/**
* @inheritdoc LSP8IdentifiableDigitalAsset
*/
@@ -86,17 +116,22 @@ abstract contract LSP8CompatibleERC721 is
public
view
virtual
- override(IERC165, ERC725YCore, LSP8IdentifiableDigitalAsset)
+ override(IERC165, LSP8IdentifiableDigitalAsset)
returns (bool)
{
return
- interfaceId == _INTERFACEID_ERC721 ||
- interfaceId == _INTERFACEID_ERC721METADATA ||
+ interfaceId == type(IERC721).interfaceId ||
+ interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
- /*
- * @inheritdoc ILSP8CompatibleERC721
+ /**
+ * @inheritdoc IERC721Metadata
+ * @notice Retrieving the token URI of tokenId `tokenId`.
+ *
+ * @dev Compatible with ERC721Metadata tokenURI. Retrieve the tokenURI for a specific `tokenId`.
+ *
+ * @return The token URI.
*/
function tokenURI(
uint256 /* tokenId */
@@ -115,18 +150,32 @@ abstract contract LSP8CompatibleERC721 is
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Retrieving the address that own tokenId `tokenId`.
+ *
+ * @dev Compatible with ERC721 ownerOf.
+ *
+ * @param tokenId The tokenId to query.
+ * @return The owner of the tokenId.
*/
- function ownerOf(uint256 tokenId) public view virtual returns (address) {
+ function ownerOf(
+ uint256 tokenId
+ ) public view virtual override returns (address) {
return tokenOwnerOf(bytes32(tokenId));
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Retrieving the address other than the token owner that is approved to transfer tokenId `tokenId` on behalf of its owner.
+ *
+ * @dev Compatible with ERC721 getApproved.
+ *
+ * @param tokenId The tokenId to query.
+ * @return The address of the operator for `tokenId`.
*/
function getApproved(
uint256 tokenId
- ) public view virtual returns (address) {
+ ) public view virtual override returns (address) {
bytes32 tokenIdAsBytes32 = bytes32(tokenId);
_existsOrError(tokenIdAsBytes32);
@@ -146,32 +195,68 @@ abstract contract LSP8CompatibleERC721 is
}
}
- /*
- * @inheritdoc ILSP8CompatibleERC721
+ /**
+ * @inheritdoc IERC721
+ * @notice Checking if address `operator` is approved to transfer any tokenId owned by address `owner`.
+ *
+ * @dev Compatible with ERC721 isApprovedForAll.
+ *
+ * @param tokenOwner The tokenOwner address to query.
+ * @param operator The operator address to query.
+ *
+ * @return Returns if the `operator` is allowed to manage all of the assets of `owner`
*/
function isApprovedForAll(
address tokenOwner,
address operator
- ) public view virtual returns (bool) {
+ ) public view virtual override returns (bool) {
return _operatorApprovals[tokenOwner][operator];
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Calling `approve` function to approve operator at address `operator` to transfer tokenId `tokenId` on behalf of its owner.
+ *
+ * @dev Approval function compatible with ERC721 `approve(address,uint256)`.
+ *
+ * @param operator The address to approve for `tokenId`.
+ * @param tokenId The tokenId to approve.
*/
- function approve(address operator, uint256 tokenId) public virtual {
+ function approve(
+ address operator,
+ uint256 tokenId
+ ) public virtual override {
authorizeOperator(operator, bytes32(tokenId), "");
}
/**
- * @dev See {_setApprovalForAll}
+ * @inheritdoc IERC721
+ * @notice Setting the "approval for all" status of operator `_operator` to `_approved` to allow it to transfer any tokenIds on behalf of `msg.sender`.
+ *
+ * @dev Enable or disable approval for a third party ("operator") to manage all of `msg.sender`'s assets. The contract MUST allow multiple operators per owner.
+ * See {_setApprovalForAll}
+ *
+ * @param operator Address to add to the set of authorized operators.
+ * @param approved True if the operator is approved, false to revoke approval.
+ *
+ * @custom:events {ApprovalForAll} event
*/
- function setApprovalForAll(address operator, bool approved) public virtual {
+ function setApprovalForAll(
+ address operator,
+ bool approved
+ ) public virtual override {
_setApprovalForAll(msg.sender, operator, approved);
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Calling `transferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`.
+ *
+ * @dev Transfer functions from the ERC721 standard interface.
+ *
+ * @param from The sending address.
+ * @param to The receiving address.
+ * @param tokenId The tokenId to transfer.
*
* @custom:info This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`.
*/
@@ -179,12 +264,19 @@ abstract contract LSP8CompatibleERC721 is
address from,
address to,
uint256 tokenId
- ) public virtual {
+ ) public virtual override {
_transfer(from, to, bytes32(tokenId), true, "");
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Calling `safeTransferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`.
+ *
+ * @dev Safe Transfer function without optional data from the ERC721 standard interface.
+ *
+ * @param from The sending address.
+ * @param to The receiving address.
+ * @param tokenId The tokenId to transfer.
*
* @custom:info This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`.
*/
@@ -192,12 +284,20 @@ abstract contract LSP8CompatibleERC721 is
address from,
address to,
uint256 tokenId
- ) public virtual {
+ ) public virtual override {
_safeTransfer(from, to, tokenId, "");
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Calling `safeTransferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`.
+ *
+ * @dev Safe Transfer function with optional data from the ERC721 standard interface.
+ *
+ * @param from The sending address.
+ * @param to The receiving address.
+ * @param tokenId The tokenId to transfer.
+ * @param data The data to be sent with the transfer.
*
* @custom:info This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`.
*/
@@ -206,14 +306,14 @@ abstract contract LSP8CompatibleERC721 is
address to,
uint256 tokenId,
bytes memory data
- ) public virtual {
+ ) public virtual override {
_safeTransfer(from, to, tokenId, data);
}
// --- Overrides
/**
- * @inheritdoc ILSP8IdentifiableDigitalAsset
+ * @inheritdoc LSP8IdentifiableDigitalAssetCore
*
* @custom:events
* - LSP7 {AuthorizedOperator} event.
@@ -223,14 +323,7 @@ abstract contract LSP8CompatibleERC721 is
address operator,
bytes32 tokenId,
bytes memory operatorNotificationData
- )
- public
- virtual
- override(
- ILSP8IdentifiableDigitalAsset,
- LSP8IdentifiableDigitalAssetCore
- )
- {
+ ) public virtual override {
address tokenOwner = tokenOwnerOf(tokenId);
if (
@@ -345,7 +438,7 @@ abstract contract LSP8CompatibleERC721 is
}
/**
- * @dev Approve `operator` to operate on all tokens of `tokensOwner`
+ * @dev Approve `operator` to operate on all tokens of `tokensOwner`.
*
* @custom:events {ApprovalForAll} event.
*/
@@ -405,14 +498,4 @@ abstract contract LSP8CompatibleERC721 is
}
}
}
-
- /**
- * @inheritdoc LSP8IdentifiableDigitalAsset
- */
- function _setData(
- bytes32 key,
- bytes memory value
- ) internal virtual override(LSP8IdentifiableDigitalAsset, ERC725YCore) {
- super._setData(key, value);
- }
}
diff --git a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol b/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol
index 851a0e361..2fd3f5210 100644
--- a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol
+++ b/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol
@@ -2,14 +2,14 @@
pragma solidity ^0.8.12;
// interfaces
-import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
+import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol";
import {
IERC721Receiver
-} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
-import {ILSP8CompatibleERC721} from "./ILSP8CompatibleERC721.sol";
+} from "@openzeppelin/contracts/interfaces/IERC721Receiver.sol";
import {
- ILSP8IdentifiableDigitalAsset
-} from "../ILSP8IdentifiableDigitalAsset.sol";
+ IERC721Metadata,
+ IERC721
+} from "@openzeppelin/contracts/interfaces/IERC721Metadata.sol";
// libraries
import {
@@ -19,15 +19,9 @@ import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";
// modules
import {
- LSP4Compatibility
-} from "../../LSP4DigitalAssetMetadata/LSP4Compatibility.sol";
-import {
- LSP8IdentifiableDigitalAssetInitAbstract,
- ERC725YCore
+ LSP8IdentifiableDigitalAssetCore,
+ LSP8IdentifiableDigitalAssetInitAbstract
} from "../LSP8IdentifiableDigitalAssetInitAbstract.sol";
-import {
- LSP8IdentifiableDigitalAssetCore
-} from "../LSP8IdentifiableDigitalAssetCore.sol";
// errors
import {
@@ -40,20 +34,17 @@ import {
// constants
import {
- _LSP4_METADATA_KEY
+ _LSP4_METADATA_KEY,
+ _LSP4_TOKEN_NAME_KEY,
+ _LSP4_TOKEN_SYMBOL_KEY
} from "../../LSP4DigitalAssetMetadata/LSP4Constants.sol";
-import {
- _INTERFACEID_ERC721,
- _INTERFACEID_ERC721METADATA
-} from "./ILSP8CompatibleERC721.sol";
/**
* @dev LSP8 extension, for compatibility for clients / tools that expect ERC721.
*/
abstract contract LSP8CompatibleERC721InitAbstract is
- ILSP8CompatibleERC721,
- LSP8IdentifiableDigitalAssetInitAbstract,
- LSP4Compatibility
+ IERC721Metadata,
+ LSP8IdentifiableDigitalAssetInitAbstract
{
using EnumerableSet for EnumerableSet.AddressSet;
@@ -85,6 +76,45 @@ abstract contract LSP8CompatibleERC721InitAbstract is
);
}
+ /**
+ * @inheritdoc IERC721Metadata
+ * @dev Returns the name of the token.
+ * For compatibility with clients & tools that expect ERC721.
+ *
+ * @return The name of the token
+ */
+ function name() public view virtual override returns (string memory) {
+ bytes memory data = _getData(_LSP4_TOKEN_NAME_KEY);
+ return string(data);
+ }
+
+ /**
+ * @inheritdoc IERC721Metadata
+ * @dev Returns the symbol of the token, usually a shorter version of the name.
+ * For compatibility with clients & tools that expect ERC721.
+ *
+ * @return The symbol of the token
+ */
+ function symbol() public view virtual override returns (string memory) {
+ bytes memory data = _getData(_LSP4_TOKEN_SYMBOL_KEY);
+ return string(data);
+ }
+
+ /**
+ * @inheritdoc LSP8IdentifiableDigitalAssetCore
+ */
+ function balanceOf(
+ address tokenOwner
+ )
+ public
+ view
+ virtual
+ override(IERC721, LSP8IdentifiableDigitalAssetCore)
+ returns (uint256)
+ {
+ return super.balanceOf(tokenOwner);
+ }
+
/**
* @inheritdoc LSP8IdentifiableDigitalAssetInitAbstract
*/
@@ -94,21 +124,26 @@ abstract contract LSP8CompatibleERC721InitAbstract is
public
view
virtual
- override(IERC165, ERC725YCore, LSP8IdentifiableDigitalAssetInitAbstract)
+ override(IERC165, LSP8IdentifiableDigitalAssetInitAbstract)
returns (bool)
{
return
- interfaceId == _INTERFACEID_ERC721 ||
- interfaceId == _INTERFACEID_ERC721METADATA ||
+ interfaceId == type(IERC721).interfaceId ||
+ interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721Metadata
+ * @notice Retrieving the token URI of tokenId `tokenId`.
+ *
+ * @dev Compatible with ERC721Metadata tokenURI. Retrieve the tokenURI for a specific `tokenId`.
+ *
+ * @return The token URI.
*/
function tokenURI(
uint256 /* tokenId */
- ) public view virtual returns (string memory) {
+ ) public view virtual override returns (string memory) {
bytes memory data = _getData(_LSP4_METADATA_KEY);
// offset = bytes4(hashSig) + bytes32(contentHash) -> 4 + 32 = 36
@@ -123,18 +158,32 @@ abstract contract LSP8CompatibleERC721InitAbstract is
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Retrieving the address that own tokenId `tokenId`.
+ *
+ * @dev Compatible with ERC721 ownerOf.
+ *
+ * @param tokenId The tokenId to query.
+ * @return The owner of the tokenId.
*/
- function ownerOf(uint256 tokenId) public view virtual returns (address) {
+ function ownerOf(
+ uint256 tokenId
+ ) public view virtual override returns (address) {
return tokenOwnerOf(bytes32(tokenId));
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Retrieving the address other than the token owner that is approved to transfer tokenId `tokenId` on behalf of its owner.
+ *
+ * @dev Compatible with ERC721 getApproved.
+ *
+ * @param tokenId The tokenId to query.
+ * @return The address of the operator for `tokenId`.
*/
function getApproved(
uint256 tokenId
- ) public view virtual returns (address) {
+ ) public view virtual override returns (address) {
bytes32 tokenIdAsBytes32 = bytes32(tokenId);
_existsOrError(tokenIdAsBytes32);
@@ -154,33 +203,69 @@ abstract contract LSP8CompatibleERC721InitAbstract is
}
}
- /*
- * @inheritdoc ILSP8CompatibleERC721
+ /**
+ * @inheritdoc IERC721
+ * @notice Checking if address `operator` is approved to transfer any tokenId owned by address `owner`.
+ *
+ * @dev Compatible with ERC721 isApprovedForAll.
+ *
+ * @param tokenOwner The tokenOwner address to query.
+ * @param operator The operator address to query.
+ *
+ * @return Returns if the `operator` is allowed to manage all of the assets of `owner`
*/
function isApprovedForAll(
address tokenOwner,
address operator
- ) public view virtual returns (bool) {
+ ) public view virtual override returns (bool) {
return _operatorApprovals[tokenOwner][operator];
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Calling `approve` function to approve operator at address `operator` to transfer tokenId `tokenId` on behalf of its owner.
+ *
+ * @dev Approval function compatible with ERC721 `approve(address,uint256)`.
+ *
+ * @param operator The address to approve for `tokenId`.
+ * @param tokenId The tokenId to approve.
*/
- function approve(address operator, uint256 tokenId) public virtual {
+ function approve(
+ address operator,
+ uint256 tokenId
+ ) public virtual override {
authorizeOperator(operator, bytes32(tokenId), "");
emit Approval(tokenOwnerOf(bytes32(tokenId)), operator, tokenId);
}
/**
- * @dev See {_setApprovalForAll}
+ * @inheritdoc IERC721
+ * @notice Setting the "approval for all" status of operator `_operator` to `_approved` to allow it to transfer any tokenIds on behalf of `msg.sender`.
+ *
+ * @dev Enable or disable approval for a third party ("operator") to manage all of `msg.sender`'s assets. The contract MUST allow multiple operators per owner.
+ * See {_setApprovalForAll}
+ *
+ * @param operator Address to add to the set of authorized operators.
+ * @param approved True if the operator is approved, false to revoke approval.
+ *
+ * @custom:events {ApprovalForAll} event
*/
- function setApprovalForAll(address operator, bool approved) public virtual {
+ function setApprovalForAll(
+ address operator,
+ bool approved
+ ) public virtual override {
_setApprovalForAll(msg.sender, operator, approved);
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Calling `transferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`.
+ *
+ * @dev Transfer functions from the ERC721 standard interface.
+ *
+ * @param from The sending address.
+ * @param to The receiving address.
+ * @param tokenId The tokenId to transfer.
*
* @custom:info This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`.
*/
@@ -188,12 +273,19 @@ abstract contract LSP8CompatibleERC721InitAbstract is
address from,
address to,
uint256 tokenId
- ) public virtual {
+ ) public virtual override {
_transfer(from, to, bytes32(tokenId), true, "");
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Calling `safeTransferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`.
+ *
+ * @dev Safe Transfer function without optional data from the ERC721 standard interface.
+ *
+ * @param from The sending address.
+ * @param to The receiving address.
+ * @param tokenId The tokenId to transfer.
*
* @custom:info This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`.
*/
@@ -201,12 +293,20 @@ abstract contract LSP8CompatibleERC721InitAbstract is
address from,
address to,
uint256 tokenId
- ) public virtual {
+ ) public virtual override {
_safeTransfer(from, to, tokenId, "");
}
/**
- * @inheritdoc ILSP8CompatibleERC721
+ * @inheritdoc IERC721
+ * @notice Calling `safeTransferFrom` function with `data` to transfer tokenId `tokenId` from address `from` to address `to`.
+ *
+ * @dev Safe Transfer function with optional data from the ERC721 standard interface.
+ *
+ * @param from The sending address.
+ * @param to The receiving address.
+ * @param tokenId The tokenId to transfer.
+ * @param data The data to be sent with the transfer.
*
* @custom:info This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`.
*/
@@ -215,14 +315,14 @@ abstract contract LSP8CompatibleERC721InitAbstract is
address to,
uint256 tokenId,
bytes memory data
- ) public virtual {
+ ) public virtual override {
_safeTransfer(from, to, tokenId, data);
}
// --- Overrides
/**
- * @inheritdoc ILSP8IdentifiableDigitalAsset
+ * @inheritdoc LSP8IdentifiableDigitalAssetCore
*
* @custom:events
* - LSP7 {AuthorizedOperator} event.
@@ -232,14 +332,7 @@ abstract contract LSP8CompatibleERC721InitAbstract is
address operator,
bytes32 tokenId,
bytes memory operatorNotificationData
- )
- public
- virtual
- override(
- ILSP8IdentifiableDigitalAsset,
- LSP8IdentifiableDigitalAssetCore
- )
- {
+ ) public virtual override {
address tokenOwner = tokenOwnerOf(tokenId);
if (
@@ -354,7 +447,7 @@ abstract contract LSP8CompatibleERC721InitAbstract is
}
/**
- * @dev Approve `operator` to operate on all tokens of `tokensOwner`
+ * @dev Approve `operator` to operate on all tokens of `tokensOwner`.
*
* @custom:events {ApprovalForAll} event.
*/
@@ -414,18 +507,4 @@ abstract contract LSP8CompatibleERC721InitAbstract is
}
}
}
-
- /**
- * @inheritdoc LSP8IdentifiableDigitalAssetInitAbstract
- */
- function _setData(
- bytes32 key,
- bytes memory value
- )
- internal
- virtual
- override(LSP8IdentifiableDigitalAssetInitAbstract, ERC725YCore)
- {
- super._setData(key, value);
- }
}
diff --git a/contracts/Mocks/ERC165Interfaces.sol b/contracts/Mocks/ERC165Interfaces.sol
index 4fcd847b3..54b90ab3c 100644
--- a/contracts/Mocks/ERC165Interfaces.sol
+++ b/contracts/Mocks/ERC165Interfaces.sol
@@ -13,13 +13,16 @@ import {
OwnableUnset
} from "@erc725/smart-contracts/contracts/custom/OwnableUnset.sol";
-import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
+import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol";
+import {
+ IERC20Metadata
+} from "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";
+import {IERC721} from "@openzeppelin/contracts/interfaces/IERC721.sol";
import {
IERC721Metadata
-} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
-import {IERC777} from "@openzeppelin/contracts/token/ERC777/IERC777.sol";
-import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
+} from "@openzeppelin/contracts/interfaces/IERC721Metadata.sol";
+import {IERC777} from "@openzeppelin/contracts/interfaces/IERC777.sol";
+import {IERC1155} from "@openzeppelin/contracts/interfaces/IERC1155.sol";
import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import {IERC223} from "./Tokens/IERC223.sol";
@@ -278,6 +281,10 @@ contract CalculateERCInterfaces {
return type(IERC20).interfaceId;
}
+ function calculateInterfaceERC20Metadata() public pure returns (bytes4) {
+ return type(IERC20Metadata).interfaceId;
+ }
+
function calculateInterfaceERC721() public pure returns (bytes4) {
return type(IERC721).interfaceId;
}
diff --git a/contracts/Mocks/Tokens/LSP4CompatibilityTester.sol b/contracts/Mocks/Tokens/LSP4CompatibilityTester.sol
deleted file mode 100644
index 3edb6de8b..000000000
--- a/contracts/Mocks/Tokens/LSP4CompatibilityTester.sol
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-pragma solidity ^0.8.4;
-
-// modules
-import {ERC725Y} from "@erc725/smart-contracts/contracts/ERC725Y.sol";
-import {
- LSP4Compatibility
-} from "../../LSP4DigitalAssetMetadata/LSP4Compatibility.sol";
-
-// constants
-import {
- _LSP4_TOKEN_NAME_KEY,
- _LSP4_TOKEN_SYMBOL_KEY
-} from "../../LSP4DigitalAssetMetadata/LSP4Constants.sol";
-
-contract LSP4CompatibilityTester is ERC725Y, LSP4Compatibility {
- constructor(
- string memory name,
- string memory symbol,
- address newOwner
- ) ERC725Y(newOwner) {
- _setData(_LSP4_TOKEN_NAME_KEY, bytes(name));
- _setData(_LSP4_TOKEN_SYMBOL_KEY, bytes(symbol));
- }
-}
diff --git a/docs/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.md b/docs/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.md
deleted file mode 100644
index 2b822c453..000000000
--- a/docs/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.md
+++ /dev/null
@@ -1,583 +0,0 @@
-
-
-
-# LSP4Compatibility
-
-:::info Standard Specifications
-
-[`LSP-4-DigitalAssetMetadata`](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md)
-
-:::
-:::info Solidity implementation
-
-[`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol)
-
-:::
-
-> LSP4Compatibility
-
-LSP4 extension, for compatibility with clients & tools that expect ERC20/721.
-
-## Public Methods
-
-Public methods are accessible externally from users, allowing interaction with this function from dApps or other smart contracts.
-When marked as 'public', a method can be called both externally and internally, on the other hand, when marked as 'external', a method can only be called externally.
-
-### getData
-
-:::note References
-
-- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#getdata)
-- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol)
-- Function signature: `getData(bytes32)`
-- Function selector: `0x54f6127f`
-
-:::
-
-```solidity
-function getData(bytes32 dataKey) external view returns (bytes dataValue);
-```
-
-_Reading the ERC725Y storage for data key `dataKey` returned the following value: `dataValue`._
-
-Get in the ERC725Y storage the bytes data stored at a specific data key `dataKey`.
-
-#### Parameters
-
-| Name | Type | Description |
-| --------- | :-------: | --------------------------------------------- |
-| `dataKey` | `bytes32` | The data key for which to retrieve the value. |
-
-#### Returns
-
-| Name | Type | Description |
-| ----------- | :-----: | ---------------------------------------------------- |
-| `dataValue` | `bytes` | The bytes value stored under the specified data key. |
-
-
-
-### getDataBatch
-
-:::note References
-
-- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#getdatabatch)
-- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol)
-- Function signature: `getDataBatch(bytes32[])`
-- Function selector: `0xdedff9c6`
-
-:::
-
-```solidity
-function getDataBatch(
- bytes32[] dataKeys
-) external view returns (bytes[] dataValues);
-```
-
-_Reading the ERC725Y storage for data keys `dataKeys` returned the following values: `dataValues`._
-
-Get in the ERC725Y storage the bytes data stored at multiple data keys `dataKeys`.
-
-#### Parameters
-
-| Name | Type | Description |
-| ---------- | :---------: | ------------------------------------------ |
-| `dataKeys` | `bytes32[]` | The array of keys which values to retrieve |
-
-#### Returns
-
-| Name | Type | Description |
-| ------------ | :-------: | ----------------------------------------- |
-| `dataValues` | `bytes[]` | The array of data stored at multiple keys |
-
-
-
-### name
-
-:::note References
-
-- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#name)
-- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol)
-- Function signature: `name()`
-- Function selector: `0x06fdde03`
-
-:::
-
-```solidity
-function name() external view returns (string);
-```
-
-Returns the name of the token.
-
-#### Returns
-
-| Name | Type | Description |
-| ---- | :------: | --------------------- |
-| `0` | `string` | The name of the token |
-
-
-
-### owner
-
-:::note References
-
-- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#owner)
-- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol)
-- Function signature: `owner()`
-- Function selector: `0x8da5cb5b`
-
-:::
-
-```solidity
-function owner() external view returns (address);
-```
-
-Returns the address of the current owner.
-
-#### Returns
-
-| Name | Type | Description |
-| ---- | :-------: | ----------- |
-| `0` | `address` | - |
-
-
-
-### renounceOwnership
-
-:::note References
-
-- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#renounceownership)
-- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol)
-- Function signature: `renounceOwnership()`
-- Function selector: `0x715018a6`
-
-:::
-
-```solidity
-function renounceOwnership() external nonpayable;
-```
-
-Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.
-
-
-
-### setData
-
-:::note References
-
-- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#setdata)
-- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol)
-- Function signature: `setData(bytes32,bytes)`
-- Function selector: `0x7f23690c`
-
-:::
-
-:::caution Warning
-
-**Note for developers:** despite the fact that this function is set as `payable`, if the function is not intended to receive value (= native tokens), **an additional check should be implemented to ensure that `msg.value` sent was equal to 0**.
-
-:::
-
-```solidity
-function setData(bytes32 dataKey, bytes dataValue) external payable;
-```
-
-_Setting the following data key value pair in the ERC725Y storage. Data key: `dataKey`, data value: `dataValue`._
-
-Sets a single bytes value `dataValue` in the ERC725Y storage for a specific data key `dataKey`. The function is marked as payable to enable flexibility on child contracts. For instance to implement a fee mechanism for setting specific data.
-
-
- -**Requirements:** - -- SHOULD only be callable by the [`owner`](#owner). - -- -
- -**Emitted events:** - -- [`DataChanged`](#datachanged) event. - -- -#### Parameters - -| Name | Type | Description | -| ----------- | :-------: | ------------------------------------------ | -| `dataKey` | `bytes32` | The data key for which to set a new value. | -| `dataValue` | `bytes` | The new bytes value to set. | - -
- -**Requirements:** - -- SHOULD only be callable by the [`owner`](#owner) of the contract. - -- -
- -**Emitted events:** - -- [`DataChanged`](#datachanged) event **for each data key/value pair set**. - -- -#### Parameters - -| Name | Type | Description | -| ------------ | :---------: | ---------------------------------------------------- | -| `dataKeys` | `bytes32[]` | An array of data keys to set bytes values for. | -| `dataValues` | `bytes[]` | An array of bytes values to set for each `dataKeys`. | - -
- -**Emitted events:** - -- [`DataChanged`](#datachanged) event emitted after a successful `setData` call. - -- -#### Parameters - -| Name | Type | Description | -| ----------- | :-------: | ------------------------------------------------------------------------------- | -| `dataKey` | `bytes32` | A bytes32 data key to write the associated `bytes` value to the store. | -| `dataValue` | `bytes` | The `bytes` value to associate with the given `dataKey` in the ERC725Y storage. | - -
+ +**Emitted events:** + +- [`ApprovalForAll`](#approvalforall) event + +#### Parameters -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `operator` | `address` | - | -| `approved` | `bool` | - | +| Name | Type | Description | +| ---------- | :-------: | ----------------------------------------------------------- | +| `operator` | `address` | Address to add to the set of authorized operators. | +| `approved` | `bool` | True if the operator is approved, false to revoke approval. |
@@ -1398,20 +1419,18 @@ Approve `operator` to operate on all tokens of `tokensOwner` ::: ```solidity -event Approval(address indexed owner, address indexed operator, uint256 indexed tokenId); +event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); ``` -_ERC721 `Approval` compatible event emitted. Successfully approved operator `operator` to operate on tokenId `tokenId` on behalf of token owner `owner`._ - Emitted when the allowance of a `spender` for an `owner` is set by a call to [`approve`](#approve). `value` is the new allowance. #### Parameters -| Name | Type | Description | -| ------------------------ | :-------: | ---------------------------- | -| `owner` **`indexed`** | `address` | The account giving approval | -| `operator` **`indexed`** | `address` | The address set as operator. | -| `tokenId` **`indexed`** | `uint256` | The approved tokenId. | +| Name | Type | Description | +| ------------------------ | :-------: | ----------- | +| `owner` **`indexed`** | `address` | - | +| `approved` **`indexed`** | `address` | - | +| `tokenId` **`indexed`** | `uint256` | - |
@@ -1430,17 +1449,15 @@ Emitted when the allowance of a `spender` for an `owner` is set by a call to [`a event ApprovalForAll(address indexed owner, address indexed operator, bool approved); ``` -_ERC721 `ApprovalForAll` compatible event emitted. Successfully set "approved for all" status to `approved` for operator `operator` for token owner `owner`._ - Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to `approved`. #### Parameters -| Name | Type | Description | -| ------------------------ | :-------: | ---------------------------------------------- | -| `owner` **`indexed`** | `address` | The address of the owner of tokenIds. | -| `operator` **`indexed`** | `address` | The address set as operator. | -| `approved` | `bool` | If `operator` is approved for all NFTs or not. | +| Name | Type | Description | +| ------------------------ | :-------: | ----------- | +| `owner` **`indexed`** | `address` | - | +| `operator` **`indexed`** | `address` | - | +| `approved` | `bool` | - |
@@ -1558,26 +1575,27 @@ Emitted when `tokenOwner` disables `operator` to transfer or burn `tokenId` on i - Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#transfer) - Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Event signature: `Transfer(address,address,uint256)` -- Event topic hash: `0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef` +- Event signature: `Transfer(address,address,address,bytes32,bool,bytes)` +- Event topic hash: `0xb333c813a7426a7a11e2b190cad52c44119421594b47f6f32ace6d8c7207b2bf` ::: ```solidity -event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); +event Transfer(address operator, address indexed from, address indexed to, bytes32 indexed tokenId, bool force, bytes data); ``` -_ERC721 `Transfer` compatible event emitted. Successfully transferred tokenId `tokenId` from `from` to `to`._ - -Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. +Emitted when `tokenId` token is transferred from the `from` to the `to` address. #### Parameters -| Name | Type | Description | -| ----------------------- | :-------: | ------------------------ | -| `from` **`indexed`** | `address` | The sending address | -| `to` **`indexed`** | `address` | The receiving address | -| `tokenId` **`indexed`** | `uint256` | The tokenId to transfer. | +| Name | Type | Description | +| ----------------------- | :-------: | ---------------------------------------------------------------------------------------------------------------------------------- | +| `operator` | `address` | The address of operator that sent the `tokenId` | +| `from` **`indexed`** | `address` | The previous owner of the `tokenId` | +| `to` **`indexed`** | `address` | The new owner of `tokenId` | +| `tokenId` **`indexed`** | `bytes32` | The tokenId that was transferred | +| `force` | `bool` | If the token transfer enforces the `to` recipient address to be a contract that implements the LSP1 standard or not. | +| `data` | `bytes` | Any additional data the caller included by the caller during the transfer, and sent in the hooks to the `from` and `to` addresses. |
@@ -1587,27 +1605,24 @@ Emitted when `value` tokens are moved from one account (`from`) to another (`to` - Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#transfer) - Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Event signature: `Transfer(address,address,address,bytes32,bool,bytes)` -- Event topic hash: `0xb333c813a7426a7a11e2b190cad52c44119421594b47f6f32ace6d8c7207b2bf` +- Event signature: `Transfer(address,address,uint256)` +- Event topic hash: `0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef` ::: ```solidity -event Transfer(address operator, address indexed from, address indexed to, bytes32 indexed tokenId, bool force, bytes data); +event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); ``` -Emitted when `tokenId` token is transferred from the `from` to the `to` address. +Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. #### Parameters -| Name | Type | Description | -| ----------------------- | :-------: | ---------------------------------------------------------------------------------------------------------------------------------- | -| `operator` | `address` | The address of operator that sent the `tokenId` | -| `from` **`indexed`** | `address` | The previous owner of the `tokenId` | -| `to` **`indexed`** | `address` | The new owner of `tokenId` | -| `tokenId` **`indexed`** | `bytes32` | The tokenId that was transferred | -| `force` | `bool` | If the token transfer enforces the `to` recipient address to be a contract that implements the LSP1 standard or not. | -| `data` | `bytes` | Any additional data the caller included by the caller during the transfer, and sent in the hooks to the `from` and `to` addresses. | +| Name | Type | Description | +| ----------------------- | :-------: | ----------- | +| `from` **`indexed`** | `address` | - | +| `to` **`indexed`** | `address` | - | +| `tokenId` **`indexed`** | `uint256` | - |
diff --git a/docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.md b/docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.md index 0e2b550cf..232dbd9d5 100644 --- a/docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.md +++ b/docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.md @@ -97,7 +97,7 @@ receive() external payable; function approve(address operator, uint256 tokenId) external nonpayable; ``` -_Calling `approve` function on `ILSP8CompatibleERC721` contract. Approving operator at address `operator` to transfer tokenId `tokenId` on behalf of its owner._ +_Calling `approve` function to approve operator at address `operator` to transfer tokenId `tokenId` on behalf of its owner._ Approval function compatible with ERC721 `approve(address,uint256)`. @@ -331,18 +331,22 @@ function isApprovedForAll( ) external view returns (bool); ``` +_Checking if address `operator` is approved to transfer any tokenId owned by address `owner`._ + +Compatible with ERC721 isApprovedForAll. + #### Parameters -| Name | Type | Description | -| ------------ | :-------: | ----------- | -| `tokenOwner` | `address` | - | -| `operator` | `address` | - | +| Name | Type | Description | +| ------------ | :-------: | -------------------------------- | +| `tokenOwner` | `address` | The tokenOwner address to query. | +| `operator` | `address` | The operator address to query. | #### Returns -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | +| Name | Type | Description | +| ---- | :----: | --------------------------------------------------------------------------- | +| `0` | `bool` | Returns if the `operator` is allowed to manage all of the assets of `owner` |
@@ -431,7 +435,7 @@ Public [`_mint`](#_mint) function only callable by the [`owner`](#owner). function name() external view returns (string); ``` -Returns the name of the token. +Returns the name of the token. For compatibility with clients & tools that expect ERC721. #### Returns @@ -574,7 +578,7 @@ function safeTransferFrom( ) external nonpayable; ``` -_Calling `safeTransferFrom` function on `ILSP8CompatibleERC721` contract. Transferring tokenId `tokenId` from address `from` to address `to`._ +_Calling `safeTransferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`._ Safe Transfer function without optional data from the ERC721 standard interface. @@ -614,7 +618,7 @@ function safeTransferFrom( ) external nonpayable; ``` -_Calling `safeTransferFrom` function with `data` on `ILSP8CompatibleERC721` contract. Transferring tokenId `tokenId` from address `from` to address `to`._ +_Calling `safeTransferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`._ Safe Transfer function with optional data from the ERC721 standard interface. @@ -644,14 +648,24 @@ Safe Transfer function with optional data from the ERC721 standard interface. function setApprovalForAll(address operator, bool approved) external nonpayable; ``` -See [`_setApprovalForAll`](#_setapprovalforall) +_Setting the "approval for all" status of operator `_operator` to `_approved` to allow it to transfer any tokenIds on behalf of `msg.sender`._ + +Enable or disable approval for a third party ("operator") to manage all of `msg.sender`'s assets. The contract MUST allow multiple operators per owner. See [`_setApprovalForAll`](#_setapprovalforall) + ++ +**Emitted events:** + +- [`ApprovalForAll`](#approvalforall) event + +#### Parameters -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `operator` | `address` | - | -| `approved` | `bool` | - | +| Name | Type | Description | +| ---------- | :-------: | ----------------------------------------------------------- | +| `operator` | `address` | Address to add to the set of authorized operators. | +| `approved` | `bool` | True if the operator is approved, false to revoke approval. |
@@ -801,7 +815,7 @@ Returns true if this contract implements the interface defined by `interfaceId`. function symbol() external view returns (string); ``` -Returns the symbol of the token, usually a shorter version of the name. +Returns the symbol of the token, usually a shorter version of the name. For compatibility with clients & tools that expect ERC721. #### Returns @@ -888,6 +902,10 @@ Returns the list of `tokenIds` for the `tokenOwner` address. function tokenURI(uint256) external view returns (string); ``` +_Retrieving the token URI of tokenId `tokenId`._ + +Compatible with ERC721Metadata tokenURI. Retrieve the tokenURI for a specific `tokenId`. + #### Parameters | Name | Type | Description | @@ -896,9 +914,9 @@ function tokenURI(uint256) external view returns (string); #### Returns -| Name | Type | Description | -| ---- | :------: | ----------- | -| `0` | `string` | - | +| Name | Type | Description | +| ---- | :------: | -------------- | +| `0` | `string` | The token URI. |
@@ -1022,7 +1040,7 @@ function transferFrom( ) external nonpayable; ``` -_Calling `transferFrom` function on `ILSP8CompatibleERC721` contract. Transferring tokenId `tokenId` from address `from` to address `to`._ +_Calling `transferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`._ Transfer functions from the ERC721 standard interface. @@ -1118,9 +1136,12 @@ mapping(bytes32 => bytes) _store ### \_setData ```solidity -function _setData(bytes32 key, bytes value) internal nonpayable; +function _setData(bytes32 dataKey, bytes dataValue) internal nonpayable; ``` +The ERC725Y data key `_LSP8_TOKENID_TYPE_KEY` cannot be changed +once the identifiable digital asset contract has been deployed. +
### \_isOperatorOrOwner @@ -1414,7 +1435,7 @@ function _setApprovalForAll( ) internal nonpayable; ``` -Approve `operator` to operate on all tokens of `tokensOwner` +Approve `operator` to operate on all tokens of `tokensOwner`.@@ -1440,20 +1461,18 @@ Approve `operator` to operate on all tokens of `tokensOwner` ::: ```solidity -event Approval(address indexed owner, address indexed operator, uint256 indexed tokenId); +event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); ``` -_ERC721 `Approval` compatible event emitted. Successfully approved operator `operator` to operate on tokenId `tokenId` on behalf of token owner `owner`._ - Emitted when the allowance of a `spender` for an `owner` is set by a call to [`approve`](#approve). `value` is the new allowance. #### Parameters -| Name | Type | Description | -| ------------------------ | :-------: | ---------------------------- | -| `owner` **`indexed`** | `address` | The account giving approval | -| `operator` **`indexed`** | `address` | The address set as operator. | -| `tokenId` **`indexed`** | `uint256` | The approved tokenId. | +| Name | Type | Description | +| ------------------------ | :-------: | ----------- | +| `owner` **`indexed`** | `address` | - | +| `approved` **`indexed`** | `address` | - | +| `tokenId` **`indexed`** | `uint256` | - |
@@ -1472,17 +1491,15 @@ Emitted when the allowance of a `spender` for an `owner` is set by a call to [`a event ApprovalForAll(address indexed owner, address indexed operator, bool approved); ``` -_ERC721 `ApprovalForAll` compatible event emitted. Successfully set "approved for all" status to `approved` for operator `operator` for token owner `owner`._ - Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to `approved`. #### Parameters -| Name | Type | Description | -| ------------------------ | :-------: | ---------------------------------------------- | -| `owner` **`indexed`** | `address` | The address of the owner of tokenIds. | -| `operator` **`indexed`** | `address` | The address set as operator. | -| `approved` | `bool` | If `operator` is approved for all NFTs or not. | +| Name | Type | Description | +| ------------------------ | :-------: | ----------- | +| `owner` **`indexed`** | `address` | - | +| `operator` **`indexed`** | `address` | - | +| `approved` | `bool` | - |
@@ -1600,26 +1617,27 @@ Emitted when `tokenOwner` disables `operator` to transfer or burn `tokenId` on i - Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#transfer) - Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Event signature: `Transfer(address,address,uint256)` -- Event topic hash: `0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef` +- Event signature: `Transfer(address,address,address,bytes32,bool,bytes)` +- Event topic hash: `0xb333c813a7426a7a11e2b190cad52c44119421594b47f6f32ace6d8c7207b2bf` ::: ```solidity -event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); +event Transfer(address operator, address indexed from, address indexed to, bytes32 indexed tokenId, bool force, bytes data); ``` -_ERC721 `Transfer` compatible event emitted. Successfully transferred tokenId `tokenId` from `from` to `to`._ - -Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. +Emitted when `tokenId` token is transferred from the `from` to the `to` address. #### Parameters -| Name | Type | Description | -| ----------------------- | :-------: | ------------------------ | -| `from` **`indexed`** | `address` | The sending address | -| `to` **`indexed`** | `address` | The receiving address | -| `tokenId` **`indexed`** | `uint256` | The tokenId to transfer. | +| Name | Type | Description | +| ----------------------- | :-------: | ---------------------------------------------------------------------------------------------------------------------------------- | +| `operator` | `address` | The address of operator that sent the `tokenId` | +| `from` **`indexed`** | `address` | The previous owner of the `tokenId` | +| `to` **`indexed`** | `address` | The new owner of `tokenId` | +| `tokenId` **`indexed`** | `bytes32` | The tokenId that was transferred | +| `force` | `bool` | If the token transfer enforces the `to` recipient address to be a contract that implements the LSP1 standard or not. | +| `data` | `bytes` | Any additional data the caller included by the caller during the transfer, and sent in the hooks to the `from` and `to` addresses. |
@@ -1629,27 +1647,24 @@ Emitted when `value` tokens are moved from one account (`from`) to another (`to` - Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#transfer) - Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Event signature: `Transfer(address,address,address,bytes32,bool,bytes)` -- Event topic hash: `0xb333c813a7426a7a11e2b190cad52c44119421594b47f6f32ace6d8c7207b2bf` +- Event signature: `Transfer(address,address,uint256)` +- Event topic hash: `0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef` ::: ```solidity -event Transfer(address operator, address indexed from, address indexed to, bytes32 indexed tokenId, bool force, bytes data); +event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); ``` -Emitted when `tokenId` token is transferred from the `from` to the `to` address. +Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. #### Parameters -| Name | Type | Description | -| ----------------------- | :-------: | ---------------------------------------------------------------------------------------------------------------------------------- | -| `operator` | `address` | The address of operator that sent the `tokenId` | -| `from` **`indexed`** | `address` | The previous owner of the `tokenId` | -| `to` **`indexed`** | `address` | The new owner of `tokenId` | -| `tokenId` **`indexed`** | `bytes32` | The tokenId that was transferred | -| `force` | `bool` | If the token transfer enforces the `to` recipient address to be a contract that implements the LSP1 standard or not. | -| `data` | `bytes` | Any additional data the caller included by the caller during the transfer, and sent in the hooks to the `from` and `to` addresses. | +| Name | Type | Description | +| ----------------------- | :-------: | ----------- | +| `from` **`indexed`** | `address` | - | +| `to` **`indexed`** | `address` | - | +| `tokenId` **`indexed`** | `uint256` | - |
diff --git a/dodoc/config.ts b/dodoc/config.ts index d9f4059c8..02cb032b2 100644 --- a/dodoc/config.ts +++ b/dodoc/config.ts @@ -23,7 +23,6 @@ export const dodocConfig = { 'contracts/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.sol', // tokens - 'contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol', 'contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol', 'contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol', 'contracts/LSP7DigitalAsset/extensions/LSP7Burnable.sol', diff --git a/hardhat.config.ts b/hardhat.config.ts index 175e5dad2..d621968aa 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -140,7 +140,6 @@ const config: HardhatUserConfig = { 'LSP11BasicSocialRecoveryInit', // ERC Compatible tokens // ------------------ - 'LSP4Compatibility', 'LSP7CompatibleERC20', 'LSP7CompatibleERC20InitAbstract', 'LSP7CompatibleERC20Mintable', diff --git a/package.json b/package.json index 7a73a12a6..ce39f3440 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,6 @@ "test:upinit": "hardhat test --no-compile tests/UniversalProfileInit.test.ts", "test:lsp1": "hardhat test --no-compile tests/LSP1UniversalReceiver/*.test.ts", "test:lsp2": "hardhat test --no-compile tests/LSP2ERC725YJSONSchema/LSP2UtilsLibrary.test.ts", - "test:lsp4": "hardhat test --no-compile tests/LSP4DigitalAssetMetadata/LSP4Compatibility.test.ts", "test:lsp6": "hardhat test --no-compile tests/LSP6KeyManager/LSP6KeyManager.test.ts", "test:lsp6init": "hardhat test --no-compile tests/LSP6KeyManager/LSP6KeyManagerInit.test.ts", "test:lsp7": "hardhat test --no-compile tests/LSP7DigitalAsset/standard/*.test.ts", diff --git a/scripts/interfaceIds.ts b/scripts/interfaceIds.ts index e1f63fb65..fb6c79a1a 100644 --- a/scripts/interfaceIds.ts +++ b/scripts/interfaceIds.ts @@ -11,7 +11,15 @@ const ercInterfaceDescriptions = { ERC725Y: 'General Data key-value store.', }; -const excludedInterfaces = ['ERC20', 'ERC223', 'ERC721', 'ERC721Metadata', 'ERC777', 'ERC1155']; +const excludedInterfaces = [ + 'ERC20', + 'ERC20Metadata', + 'ERC223', + 'ERC721', + 'ERC721Metadata', + 'ERC777', + 'ERC1155', +]; async function main() { const interfaces = Object.entries(INTERFACE_IDS); diff --git a/tests/LSP4DigitalAssetMetadata/LSP4Compatibility.test.ts b/tests/LSP4DigitalAssetMetadata/LSP4Compatibility.test.ts deleted file mode 100644 index fc3ced43e..000000000 --- a/tests/LSP4DigitalAssetMetadata/LSP4Compatibility.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { expect } from 'chai'; -import { ethers } from 'hardhat'; -import { LSP4CompatibilityTester, LSP4CompatibilityTester__factory } from '../../types'; - -import type { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; - -type LSP4CompatibilityTestAccounts = { - owner: SignerWithAddress; -}; - -const getNamedAccounts = async () => { - const [owner] = await ethers.getSigners(); - return { owner }; -}; - -type LSP4CompatibilityTestContext = { - accounts: LSP4CompatibilityTestAccounts; - lsp4Compatibility: LSP4CompatibilityTester; - deployParams: { - name: string; - symbol: string; - newOwner: string; - }; -}; - -describe('LSP4Compatibility', () => { - const buildTestContext = async (): Promise=> { - const accounts = await getNamedAccounts(); - const deployParams = { - name: 'Much compat', - symbol: 'WOW', - newOwner: accounts.owner.address, - }; - - const lsp4Compatibility = await new LSP4CompatibilityTester__factory(accounts.owner).deploy( - deployParams.name, - deployParams.symbol, - deployParams.newOwner, - ); - - return { accounts, lsp4Compatibility, deployParams }; - }; - - describe('when using LSP4Compatibility', () => { - let context: LSP4CompatibilityTestContext; - - before(async () => { - context = await buildTestContext(); - }); - - it('should allow reading name', async () => { - // using compatibility getter -> returns(string) - const nameAsString = await context.lsp4Compatibility.name(); - expect(nameAsString).to.equal(context.deployParams.name); - - // using getData -> returns(bytes) - const nameAsBytes = await context.lsp4Compatibility.getData( - ethers.utils.keccak256(ethers.utils.toUtf8Bytes('LSP4TokenName')), - ); - - expect(ethers.utils.toUtf8String(nameAsBytes)).to.equal(context.deployParams.name); - }); - - it('should allow reading symbol', async () => { - // using compatibility getter -> returns(string) - const symbolAsString = await context.lsp4Compatibility.symbol(); - expect(symbolAsString).to.equal(context.deployParams.symbol); - - // using getData -> returns(bytes) - const symbolAsBytes = await context.lsp4Compatibility.getData( - ethers.utils.keccak256(ethers.utils.toUtf8Bytes('LSP4TokenSymbol')), - ); - - expect(ethers.utils.toUtf8String(symbolAsBytes)).to.equal(context.deployParams.symbol); - }); - }); -}); diff --git a/tests/LSP7DigitalAsset/LSP7CompatibleERC20.behaviour.ts b/tests/LSP7DigitalAsset/LSP7CompatibleERC20.behaviour.ts index 831a6ad1e..4c9c744d5 100644 --- a/tests/LSP7DigitalAsset/LSP7CompatibleERC20.behaviour.ts +++ b/tests/LSP7DigitalAsset/LSP7CompatibleERC20.behaviour.ts @@ -1285,8 +1285,18 @@ export const shouldInitializeLikeLSP7CompatibleERC20 = ( }); describe('when the contract was initialized', () => { - it('should have registered its ERC165 interface', async () => { - expect(await context.lsp7CompatibleERC20.supportsInterface(INTERFACE_IDS.LSP7DigitalAsset)); + it('should support ERC20 interface', async () => { + expect(await context.lsp7CompatibleERC20.supportsInterface(INTERFACE_IDS.ERC20)).to.be.true; + }); + + it('should support ERC20Metadata interface', async () => { + expect(await context.lsp7CompatibleERC20.supportsInterface(INTERFACE_IDS.ERC20Metadata)).to.be + .true; + }); + + it('should support LSP7 interface', async () => { + expect(await context.lsp7CompatibleERC20.supportsInterface(INTERFACE_IDS.LSP7DigitalAsset)).to + .be.true; }); it('should have set expected entries with ERC725Y.setData', async () => { @@ -1318,5 +1328,33 @@ export const shouldInitializeLikeLSP7CompatibleERC20 = ( .withArgs(symbolKey, expectedSymbolValue); expect(await context.lsp7CompatibleERC20.getData(symbolKey)).to.equal(expectedSymbolValue); }); + + describe('when using the functions from IERC20Metadata', () => { + it('should allow reading `name()`', async () => { + // using compatibility getter -> returns(string) + const nameAsString = await context.lsp7CompatibleERC20.name(); + expect(nameAsString).to.equal(context.deployParams.name); + + // using getData -> returns(bytes) + const nameAsBytes = await context.lsp7CompatibleERC20.getData( + ethers.utils.keccak256(ethers.utils.toUtf8Bytes('LSP4TokenName')), + ); + + expect(ethers.utils.toUtf8String(nameAsBytes)).to.equal(context.deployParams.name); + }); + + it('should allow reading `symbol()`', async () => { + // using compatibility getter -> returns(string) + const symbolAsString = await context.lsp7CompatibleERC20.symbol(); + expect(symbolAsString).to.equal(context.deployParams.symbol); + + // using getData -> returns(bytes) + const symbolAsBytes = await context.lsp7CompatibleERC20.getData( + ethers.utils.keccak256(ethers.utils.toUtf8Bytes('LSP4TokenSymbol')), + ); + + expect(ethers.utils.toUtf8String(symbolAsBytes)).to.equal(context.deployParams.symbol); + }); + }); }); }; diff --git a/tests/LSP8IdentifiableDigitalAsset/LSP8CompatibleERC721.behaviour.ts b/tests/LSP8IdentifiableDigitalAsset/LSP8CompatibleERC721.behaviour.ts index 44eaf4d7d..5fc815c1b 100644 --- a/tests/LSP8IdentifiableDigitalAsset/LSP8CompatibleERC721.behaviour.ts +++ b/tests/LSP8IdentifiableDigitalAsset/LSP8CompatibleERC721.behaviour.ts @@ -1270,14 +1270,21 @@ export const shouldInitializeLikeLSP8CompatibleERC721 = ( }); describe('when the contract was initialized', () => { - it('should have registered its ERC165 interface', async () => { + it('should support ERC721 interface', async () => { + expect(await context.lsp8CompatibleERC721.supportsInterface(INTERFACE_IDS.ERC721)).to.be.true; + }); + + it('should support ERC721Metadata interface', async () => { + expect(await context.lsp8CompatibleERC721.supportsInterface(INTERFACE_IDS.ERC721Metadata)).to + .be.true; + }); + + it('should support LSP8 interface', async () => { expect( await context.lsp8CompatibleERC721.supportsInterface( INTERFACE_IDS.LSP8IdentifiableDigitalAsset, ), - ); - expect(await context.lsp8CompatibleERC721.supportsInterface(INTERFACE_IDS.ERC721)); - expect(await context.lsp8CompatibleERC721.supportsInterface(INTERFACE_IDS.ERC721Metadata)); + ).to.be.true; }); it('should have set expected entries with ERC725Y.setData', async () => { @@ -1309,5 +1316,33 @@ export const shouldInitializeLikeLSP8CompatibleERC721 = ( .withArgs(symbolKey, expectedSymbolValue); expect(await context.lsp8CompatibleERC721.getData(symbolKey)).to.equal(expectedSymbolValue); }); + + describe('when using the functions from IERC721Metadata', () => { + it('should allow reading `name()`', async () => { + // using compatibility getter -> returns(string) + const nameAsString = await context.lsp8CompatibleERC721.name(); + expect(nameAsString).to.equal(context.deployParams.name); + + // using getData -> returns(bytes) + const nameAsBytes = await context.lsp8CompatibleERC721.getData( + ethers.utils.keccak256(ethers.utils.toUtf8Bytes('LSP4TokenName')), + ); + + expect(ethers.utils.toUtf8String(nameAsBytes)).to.equal(context.deployParams.name); + }); + + it('should allow reading `symbol()`', async () => { + // using compatibility getter -> returns(string) + const symbolAsString = await context.lsp8CompatibleERC721.symbol(); + expect(symbolAsString).to.equal(context.deployParams.symbol); + + // using getData -> returns(bytes) + const symbolAsBytes = await context.lsp8CompatibleERC721.getData( + ethers.utils.keccak256(ethers.utils.toUtf8Bytes('LSP4TokenSymbol')), + ); + + expect(ethers.utils.toUtf8String(symbolAsBytes)).to.equal(context.deployParams.symbol); + }); + }); }); }; diff --git a/tests/Mocks/ERC165Interfaces.test.ts b/tests/Mocks/ERC165Interfaces.test.ts index 07bb2be05..87d68d7b9 100644 --- a/tests/Mocks/ERC165Interfaces.test.ts +++ b/tests/Mocks/ERC165Interfaces.test.ts @@ -109,6 +109,11 @@ describe('Calculate ERC interfaces', () => { expect(result).to.equal(INTERFACE_IDS.ERC20); }); + it('ERC20Metadata', async () => { + const result = await contract.calculateInterfaceERC20Metadata(); + expect(result).to.equal(INTERFACE_IDS.ERC20Metadata); + }); + it('ERC223', async () => { const result = await contract.calculateInterfaceERC223(); expect(result).to.equal(INTERFACE_IDS.ERC223);