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. | - -
- -### setDataBatch - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#setdatabatch) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Function signature: `setDataBatch(bytes32[],bytes[])` -- Function selector: `0x97902421` - -::: - -:::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 setDataBatch(bytes32[] dataKeys, bytes[] dataValues) external payable; -``` - -_Setting the following data key value pairs in the ERC725Y storage. Data keys: `dataKeys`, data values: `dataValues`._ - -Batch data setting function that behaves the same as [`setData`](#setdata) but allowing to set multiple data key/value pairs in the ERC725Y storage in the same transaction. - -
- -**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`. | - -
- -### supportsInterface - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#supportsinterface) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Function signature: `supportsInterface(bytes4)` -- Function selector: `0x01ffc9a7` - -::: - -```solidity -function supportsInterface(bytes4 interfaceId) external view returns (bool); -``` - -See [`IERC165-supportsInterface`](#ierc165-supportsinterface). - -#### Parameters - -| Name | Type | Description | -| ------------- | :------: | ----------- | -| `interfaceId` | `bytes4` | - | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | - -
- -### symbol - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#symbol) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Function signature: `symbol()` -- Function selector: `0x95d89b41` - -::: - -```solidity -function symbol() external view returns (string); -``` - -Returns the symbol of the token, usually a shorter version of the name. - -#### Returns - -| Name | Type | Description | -| ---- | :------: | ----------------------- | -| `0` | `string` | The symbol of the token | - -
- -### transferOwnership - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#transferownership) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Function signature: `transferOwnership(address)` -- Function selector: `0xf2fde38b` - -::: - -```solidity -function transferOwnership(address newOwner) external nonpayable; -``` - -Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `newOwner` | `address` | - | - -
- -## Internal Methods - -Any method labeled as `internal` serves as utility function within the contract. They can be used when writing solidity contracts that inherit from this contract. These methods can be extended or modified by overriding their internal behavior to suit specific needs. - -Internal functions cannot be called externally, whether from other smart contracts, dApp interfaces, or backend services. Their restricted accessibility ensures that they remain exclusively available within the context of the current contract, promoting controlled and encapsulated usage of these internal utilities. - -### \_checkOwner - -```solidity -function _checkOwner() internal view; -``` - -Throws if the sender is not the owner. - -
- -### \_setOwner - -```solidity -function _setOwner(address newOwner) internal nonpayable; -``` - -Changes the owner if `newOwner` and oldOwner are different -This pattern is useful in inheritance. - -
- -### \_getData - -```solidity -function _getData(bytes32 dataKey) internal view returns (bytes dataValue); -``` - -Read the value stored under a specific `dataKey` inside the underlying ERC725Y storage, -represented as a mapping of `bytes32` data keys mapped to their `bytes` data values. - -```solidity -mapping(bytes32 => bytes) _store -``` - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ----------------------------------------------------------------------- | -| `dataKey` | `bytes32` | A bytes32 data key to read the associated `bytes` value from the store. | - -#### Returns - -| Name | Type | Description | -| ----------- | :-----: | ----------------------------------------------------------------------------- | -| `dataValue` | `bytes` | The `bytes` value associated with the given `dataKey` in the ERC725Y storage. | - -
- -### \_setData - -```solidity -function _setData(bytes32 dataKey, bytes dataValue) internal nonpayable; -``` - -Write a `dataValue` to the underlying ERC725Y storage, represented as a mapping of -`bytes32` data keys mapped to their `bytes` data values. - -```solidity -mapping(bytes32 => bytes) _store -``` - -
- -**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. | - -
- -## Events - -### DataChanged - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#datachanged) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Event signature: `DataChanged(bytes32,bytes)` -- Event topic hash: `0xece574603820d07bc9b91f2a932baadf4628aabcb8afba49776529c14a6104b2` - -::: - -```solidity -event DataChanged(bytes32 indexed dataKey, bytes dataValue); -``` - -_The following data key/value pair has been changed in the ERC725Y storage: Data key: `dataKey`, data value: `dataValue`._ - -Emitted when data at a specific `dataKey` was changed to a new value `dataValue`. - -#### Parameters - -| Name | Type | Description | -| ----------------------- | :-------: | -------------------------------------------- | -| `dataKey` **`indexed`** | `bytes32` | The data key for which a bytes value is set. | -| `dataValue` | `bytes` | The value to set for the given data key. | - -
- -### OwnershipTransferred - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#ownershiptransferred) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Event signature: `OwnershipTransferred(address,address)` -- Event topic hash: `0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0` - -::: - -```solidity -event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); -``` - -#### Parameters - -| Name | Type | Description | -| ----------------------------- | :-------: | ----------- | -| `previousOwner` **`indexed`** | `address` | - | -| `newOwner` **`indexed`** | `address` | - | - -
- -## Errors - -### ERC725Y_DataKeysValuesEmptyArray - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#erc725y_datakeysvaluesemptyarray) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Error signature: `ERC725Y_DataKeysValuesEmptyArray()` -- Error hash: `0x97da5f95` - -::: - -```solidity -error ERC725Y_DataKeysValuesEmptyArray(); -``` - -Reverts when one of the array parameter provided to [`setDataBatch`](#setdatabatch) function is an empty array. - -
- -### ERC725Y_DataKeysValuesLengthMismatch - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#erc725y_datakeysvalueslengthmismatch) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Error signature: `ERC725Y_DataKeysValuesLengthMismatch()` -- Error hash: `0x3bcc8979` - -::: - -```solidity -error ERC725Y_DataKeysValuesLengthMismatch(); -``` - -Reverts when there is not the same number of elements in the `datakeys` and `dataValues` array parameters provided when calling the [`setDataBatch`](#setdatabatch) function. - -
- -### ERC725Y_MsgValueDisallowed - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#erc725y_msgvaluedisallowed) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Error signature: `ERC725Y_MsgValueDisallowed()` -- Error hash: `0xf36ba737` - -::: - -```solidity -error ERC725Y_MsgValueDisallowed(); -``` - -Reverts when sending value to the [`setData`](#setdata) or [`setDataBatch`](#setdatabatch) function. - -
- -### OwnableCallerNotTheOwner - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#ownablecallernottheowner) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Error signature: `OwnableCallerNotTheOwner(address)` -- Error hash: `0xbf1169c5` - -::: - -```solidity -error OwnableCallerNotTheOwner(address callerAddress); -``` - -Reverts when only the owner is allowed to call the function. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ---------------------------------------- | -| `callerAddress` | `address` | The address that tried to make the call. | - -
- -### OwnableCannotSetZeroAddressAsOwner - -:::note References - -- Specification details: [**LSP-4-DigitalAssetMetadata**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-4-DigitalAssetMetadata.md#ownablecannotsetzeroaddressasowner) -- Solidity implementation: [`LSP4Compatibility.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP4DigitalAssetMetadata/LSP4Compatibility.sol) -- Error signature: `OwnableCannotSetZeroAddressAsOwner()` -- Error hash: `0x1ad8836c` - -::: - -```solidity -error OwnableCannotSetZeroAddressAsOwner(); -``` - -Reverts when trying to set `address(0)` as the contract owner when deploying the contract, initializing it or transferring ownership of the contract. - -
diff --git a/docs/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.md b/docs/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.md index 2a4fa0a1a..3792dc399 100644 --- a/docs/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.md +++ b/docs/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.md @@ -93,18 +93,20 @@ function allowance( ) external view returns (uint256); ``` +Function to get operator allowance allowed to spend on behalf of `tokenOwner` from the ERC20 standard interface. + #### Parameters -| Name | Type | Description | -| ------------ | :-------: | ----------- | -| `tokenOwner` | `address` | - | -| `operator` | `address` | - | +| Name | Type | Description | +| ------------ | :-------: | ---------------------------------------- | +| `tokenOwner` | `address` | The address of the token owner | +| `operator` | `address` | The address approved by the `tokenOwner` | #### Returns -| Name | Type | Description | -| ---- | :-------: | ----------- | -| `0` | `uint256` | - | +| Name | Type | Description | +| ---- | :-------: | ------------------------------------------------- | +| `0` | `uint256` | The amount `operator` is approved by `tokenOwner` |
@@ -126,18 +128,20 @@ function approve( ) external nonpayable returns (bool); ``` +Approval function from th ERC20 standard interface. + #### Parameters -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `operator` | `address` | - | -| `amount` | `uint256` | - | +| Name | Type | Description | +| ---------- | :-------: | ----------------------------------- | +| `operator` | `address` | The address to approve for `amount` | +| `amount` | `uint256` | The amount to approve. | #### Returns -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | +| Name | Type | Description | +| ---- | :----: | ------------------------------ | +| `0` | `bool` | `true` on successful approval. |
@@ -496,7 +500,7 @@ Atomically increases the allowance granted to `operator` by the caller. This is 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 ERC20. #### Returns @@ -725,7 +729,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 ERC20. #### Returns @@ -819,18 +823,20 @@ function transfer( ) external nonpayable returns (bool); ``` +Transfer function from the ERC20 standard interface. + #### Parameters -| Name | Type | Description | -| -------- | :-------: | ----------- | -| `to` | `address` | - | -| `amount` | `uint256` | - | +| Name | Type | Description | +| -------- | :-------: | --------------------------------- | +| `to` | `address` | The address receiving tokens. | +| `amount` | `uint256` | The amount of tokens to transfer. | #### Returns -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | +| Name | Type | Description | +| ---- | :----: | ------------------------------ | +| `0` | `bool` | `true` on successful transfer. |
@@ -894,19 +900,21 @@ function transferFrom( ) external nonpayable returns (bool); ``` +Transfer functions for operators from the ERC20 standard interface. + #### Parameters -| Name | Type | Description | -| -------- | :-------: | ----------- | -| `from` | `address` | - | -| `to` | `address` | - | -| `amount` | `uint256` | - | +| Name | Type | Description | +| -------- | :-------: | --------------------------------- | +| `from` | `address` | The address sending tokens. | +| `to` | `address` | The address receiving tokens. | +| `amount` | `uint256` | The amount of tokens to transfer. | #### Returns -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | +| Name | Type | Description | +| ---- | :----: | ------------------------------ | +| `0` | `bool` | `true` on successful transfer. |
@@ -992,9 +1000,11 @@ mapping(bytes32 => bytes) _store ### \_setData ```solidity -function _setData(bytes32 key, bytes value) internal nonpayable; +function _setData(bytes32 dataKey, bytes dataValue) internal nonpayable; ``` +Save gas by emitting the [`DataChanged`](#datachanged) event with only the first 256 bytes of dataValue +
### \_updateOperator @@ -1262,11 +1272,11 @@ Emitted when the allowance of a `spender` for an `owner` is set by a call to [`a #### Parameters -| Name | Type | Description | -| ----------------------- | :-------: | --------------------------------------------------------- | -| `owner` **`indexed`** | `address` | The account giving approval | -| `spender` **`indexed`** | `address` | The account receiving approval | -| `value` | `uint256` | The amount of tokens `spender` has access to from `owner` | +| Name | Type | Description | +| ----------------------- | :-------: | ----------- | +| `owner` **`indexed`** | `address` | - | +| `spender` **`indexed`** | `address` | - | +| `value` | `uint256` | - |
@@ -1383,24 +1393,27 @@ Emitted when `tokenOwner` disables `operator` for `amount` tokens and set its [` - Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#transfer) - Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Event signature: `Transfer(address,address,uint256)` -- Event topic hash: `0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef` +- Event signature: `Transfer(address,address,address,uint256,bool,bytes)` +- Event topic hash: `0x3997e418d2cef0b3b0e907b1e39605c3f7d32dbd061e82ea5b4a770d46a160a6` ::: ```solidity -event Transfer(address indexed from, address indexed to, uint256 value); +event Transfer(address indexed operator, address indexed from, address indexed to, uint256 amount, bool force, bytes data); ``` -Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. +Emitted when the `from` transferred successfully `amount` of tokens to `to`. #### Parameters -| Name | Type | Description | -| -------------------- | :-------: | -------------------------------- | -| `from` **`indexed`** | `address` | The sending address | -| `to` **`indexed`** | `address` | The receiving address | -| `value` | `uint256` | The amount of tokens transfered. | +| Name | Type | Description | +| ------------------------ | :-------: | ---------------------------------------------------------------------------------------------------------------------------- | +| `operator` **`indexed`** | `address` | The address of the operator that executed the transfer. | +| `from` **`indexed`** | `address` | The address which tokens were sent from (balance decreased by `-amount`). | +| `to` **`indexed`** | `address` | The address that received the tokens (balance increased by `+amount`). | +| `amount` | `uint256` | The amount of tokens transferred. | +| `force` | `bool` | if the transferred enforced the `to` recipient address to be a contract that implements the LSP1 standard or not. | +| `data` | `bytes` | Any additional data included by the caller during the transfer, and sent in the LSP1 hooks to the `from` and `to` addresses. |
@@ -1410,27 +1423,24 @@ Emitted when `value` tokens are moved from one account (`from`) to another (`to` - Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#transfer) - Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Event signature: `Transfer(address,address,address,uint256,bool,bytes)` -- Event topic hash: `0x3997e418d2cef0b3b0e907b1e39605c3f7d32dbd061e82ea5b4a770d46a160a6` +- Event signature: `Transfer(address,address,uint256)` +- Event topic hash: `0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef` ::: ```solidity -event Transfer(address indexed operator, address indexed from, address indexed to, uint256 amount, bool force, bytes data); +event Transfer(address indexed from, address indexed to, uint256 value); ``` -Emitted when the `from` transferred successfully `amount` of tokens to `to`. +Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. #### Parameters -| Name | Type | Description | -| ------------------------ | :-------: | ---------------------------------------------------------------------------------------------------------------------------- | -| `operator` **`indexed`** | `address` | The address of the operator that executed the transfer. | -| `from` **`indexed`** | `address` | The address which tokens were sent from (balance decreased by `-amount`). | -| `to` **`indexed`** | `address` | The address that received the tokens (balance increased by `+amount`). | -| `amount` | `uint256` | The amount of tokens transferred. | -| `force` | `bool` | if the transferred enforced the `to` recipient address to be a contract that implements the LSP1 standard or not. | -| `data` | `bytes` | Any additional data included by the caller during the transfer, and sent in the LSP1 hooks to the `from` and `to` addresses. | +| Name | Type | Description | +| -------------------- | :-------: | ----------- | +| `from` **`indexed`** | `address` | - | +| `to` **`indexed`** | `address` | - | +| `value` | `uint256` | - |
diff --git a/docs/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.md b/docs/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.md index 232eda1a1..63ac7291f 100644 --- a/docs/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.md +++ b/docs/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.md @@ -94,18 +94,20 @@ function allowance( ) external view returns (uint256); ``` +Function to get operator allowance allowed to spend on behalf of `tokenOwner` from the ERC20 standard interface. + #### Parameters -| Name | Type | Description | -| ------------ | :-------: | ----------- | -| `tokenOwner` | `address` | - | -| `operator` | `address` | - | +| Name | Type | Description | +| ------------ | :-------: | ---------------------------------------- | +| `tokenOwner` | `address` | The address of the token owner | +| `operator` | `address` | The address approved by the `tokenOwner` | #### Returns -| Name | Type | Description | -| ---- | :-------: | ----------- | -| `0` | `uint256` | - | +| Name | Type | Description | +| ---- | :-------: | ------------------------------------------------- | +| `0` | `uint256` | The amount `operator` is approved by `tokenOwner` |
@@ -127,18 +129,20 @@ function approve( ) external nonpayable returns (bool); ``` +Approval function from th ERC20 standard interface. + #### Parameters -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `operator` | `address` | - | -| `amount` | `uint256` | - | +| Name | Type | Description | +| ---------- | :-------: | ----------------------------------- | +| `operator` | `address` | The address to approve for `amount` | +| `amount` | `uint256` | The amount to approve. | #### Returns -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | +| Name | Type | Description | +| ---- | :----: | ------------------------------ | +| `0` | `bool` | `true` on successful approval. |
@@ -530,7 +534,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 ERC20. #### Returns @@ -759,7 +763,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 ERC20. #### Returns @@ -853,18 +857,20 @@ function transfer( ) external nonpayable returns (bool); ``` +Transfer function from the ERC20 standard interface. + #### Parameters -| Name | Type | Description | -| -------- | :-------: | ----------- | -| `to` | `address` | - | -| `amount` | `uint256` | - | +| Name | Type | Description | +| -------- | :-------: | --------------------------------- | +| `to` | `address` | The address receiving tokens. | +| `amount` | `uint256` | The amount of tokens to transfer. | #### Returns -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | +| Name | Type | Description | +| ---- | :----: | ------------------------------ | +| `0` | `bool` | `true` on successful transfer. |
@@ -928,19 +934,21 @@ function transferFrom( ) external nonpayable returns (bool); ``` +Transfer functions for operators from the ERC20 standard interface. + #### Parameters -| Name | Type | Description | -| -------- | :-------: | ----------- | -| `from` | `address` | - | -| `to` | `address` | - | -| `amount` | `uint256` | - | +| Name | Type | Description | +| -------- | :-------: | --------------------------------- | +| `from` | `address` | The address sending tokens. | +| `to` | `address` | The address receiving tokens. | +| `amount` | `uint256` | The amount of tokens to transfer. | #### Returns -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | +| Name | Type | Description | +| ---- | :----: | ------------------------------ | +| `0` | `bool` | `true` on successful transfer. |
@@ -1026,9 +1034,11 @@ mapping(bytes32 => bytes) _store ### \_setData ```solidity -function _setData(bytes32 key, bytes value) internal nonpayable; +function _setData(bytes32 dataKey, bytes dataValue) internal nonpayable; ``` +Save gas by emitting the [`DataChanged`](#datachanged) event with only the first 256 bytes of dataValue +
### \_updateOperator @@ -1296,11 +1306,11 @@ Emitted when the allowance of a `spender` for an `owner` is set by a call to [`a #### Parameters -| Name | Type | Description | -| ----------------------- | :-------: | --------------------------------------------------------- | -| `owner` **`indexed`** | `address` | The account giving approval | -| `spender` **`indexed`** | `address` | The account receiving approval | -| `value` | `uint256` | The amount of tokens `spender` has access to from `owner` | +| Name | Type | Description | +| ----------------------- | :-------: | ----------- | +| `owner` **`indexed`** | `address` | - | +| `spender` **`indexed`** | `address` | - | +| `value` | `uint256` | - |
@@ -1417,24 +1427,27 @@ Emitted when `tokenOwner` disables `operator` for `amount` tokens and set its [` - Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#transfer) - Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Event signature: `Transfer(address,address,uint256)` -- Event topic hash: `0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef` +- Event signature: `Transfer(address,address,address,uint256,bool,bytes)` +- Event topic hash: `0x3997e418d2cef0b3b0e907b1e39605c3f7d32dbd061e82ea5b4a770d46a160a6` ::: ```solidity -event Transfer(address indexed from, address indexed to, uint256 value); +event Transfer(address indexed operator, address indexed from, address indexed to, uint256 amount, bool force, bytes data); ``` -Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. +Emitted when the `from` transferred successfully `amount` of tokens to `to`. #### Parameters -| Name | Type | Description | -| -------------------- | :-------: | -------------------------------- | -| `from` **`indexed`** | `address` | The sending address | -| `to` **`indexed`** | `address` | The receiving address | -| `value` | `uint256` | The amount of tokens transfered. | +| Name | Type | Description | +| ------------------------ | :-------: | ---------------------------------------------------------------------------------------------------------------------------- | +| `operator` **`indexed`** | `address` | The address of the operator that executed the transfer. | +| `from` **`indexed`** | `address` | The address which tokens were sent from (balance decreased by `-amount`). | +| `to` **`indexed`** | `address` | The address that received the tokens (balance increased by `+amount`). | +| `amount` | `uint256` | The amount of tokens transferred. | +| `force` | `bool` | if the transferred enforced the `to` recipient address to be a contract that implements the LSP1 standard or not. | +| `data` | `bytes` | Any additional data included by the caller during the transfer, and sent in the LSP1 hooks to the `from` and `to` addresses. |
@@ -1444,27 +1457,24 @@ Emitted when `value` tokens are moved from one account (`from`) to another (`to` - Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#transfer) - Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Event signature: `Transfer(address,address,address,uint256,bool,bytes)` -- Event topic hash: `0x3997e418d2cef0b3b0e907b1e39605c3f7d32dbd061e82ea5b4a770d46a160a6` +- Event signature: `Transfer(address,address,uint256)` +- Event topic hash: `0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef` ::: ```solidity -event Transfer(address indexed operator, address indexed from, address indexed to, uint256 amount, bool force, bytes data); +event Transfer(address indexed from, address indexed to, uint256 value); ``` -Emitted when the `from` transferred successfully `amount` of tokens to `to`. +Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. #### Parameters -| Name | Type | Description | -| ------------------------ | :-------: | ---------------------------------------------------------------------------------------------------------------------------- | -| `operator` **`indexed`** | `address` | The address of the operator that executed the transfer. | -| `from` **`indexed`** | `address` | The address which tokens were sent from (balance decreased by `-amount`). | -| `to` **`indexed`** | `address` | The address that received the tokens (balance increased by `+amount`). | -| `amount` | `uint256` | The amount of tokens transferred. | -| `force` | `bool` | if the transferred enforced the `to` recipient address to be a contract that implements the LSP1 standard or not. | -| `data` | `bytes` | Any additional data included by the caller during the transfer, and sent in the LSP1 hooks to the `from` and `to` addresses. | +| Name | Type | Description | +| -------------------- | :-------: | ----------- | +| `from` **`indexed`** | `address` | - | +| `to` **`indexed`** | `address` | - | +| `value` | `uint256` | - |
diff --git a/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.md b/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.md index e7d8328f7..d82124210 100644 --- a/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.md +++ b/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.md @@ -90,7 +90,7 @@ Reverts whenever someone tries to send native tokens to a LSP8 contract. 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)`. @@ -324,18 +324,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` |
@@ -389,7 +393,7 @@ Returns whether `operator` address is an operator for a given `tokenId`. 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 @@ -532,7 +536,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. @@ -572,7 +576,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. @@ -602,14 +606,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. |
@@ -759,7 +773,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 @@ -846,6 +860,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 | @@ -854,9 +872,9 @@ function tokenURI(uint256) external view returns (string); #### Returns -| Name | Type | Description | -| ---- | :------: | ----------- | -| `0` | `string` | - | +| Name | Type | Description | +| ---- | :------: | -------------- | +| `0` | `string` | The token URI. |
@@ -980,7 +998,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. @@ -1076,9 +1094,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 @@ -1372,7 +1393,7 @@ function _setApprovalForAll( ) internal nonpayable; ``` -Approve `operator` to operate on all tokens of `tokensOwner` +Approve `operator` to operate on all tokens of `tokensOwner`.
@@ -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);