From 491f560ad5fbb5465477b440f89796b7f79c57ef Mon Sep 17 00:00:00 2001 From: b00ste Date: Wed, 10 Jan 2024 16:26:59 +0200 Subject: [PATCH] refactor: remove LSP7 & LSP8 compatible contracts --- .github/workflows/solc_version.yml | 2 +- .mythx.yml | 8 - .../extensions/LSP7CompatibleERC20.sol | 260 -- .../LSP7CompatibleERC20InitAbstract.sol | 273 -- .../presets/LSP7CompatibleERC20Mintable.sol | 37 - .../LSP7CompatibleERC20MintableInit.sol | 44 - ...SP7CompatibleERC20MintableInitAbstract.sol | 43 - .../extensions/LSP8CompatibleERC721.sol | 512 ---- .../LSP8CompatibleERC721InitAbstract.sol | 514 ---- .../presets/LSP8CompatibleERC721Mintable.sol | 54 - .../LSP8CompatibleERC721MintableInit.sol | 47 - ...P8CompatibleERC721MintableInitAbstract.sol | 52 - .../Tokens/LSP7CompatibleERC20InitTester.sol | 40 - .../Tokens/LSP7CompatibleERC20Tester.sol | 26 - .../Tokens/LSP8CompatibleERC721Tester.sol | 43 - .../Tokens/LSP8CompatibleERC721TesterInit.sol | 50 - .../extensions/LSP7CompatibleERC20.md | 1991 ------------- .../presets/LSP7CompatibleERC20Mintable.md | 2031 ------------- .../extensions/LSP8CompatibleERC721.md | 2527 ---------------- .../presets/LSP8CompatibleERC721Mintable.md | 2596 ----------------- dodoc/config.ts | 4 - hardhat.config.ts | 10 - .../LSP7CompatibleERC20.behaviour.ts | 1330 --------- .../proxy/LSP7CompatibleERC20Init.test.ts | 136 - .../standard/LSP7CompatibleERC20.test.ts | 61 - .../LSP8CompatibleERC721.behaviour.ts | 1337 --------- .../proxy/LSP8CompatibleERC721Init.test.ts | 143 - .../standard/LSP8CompatibleERC721.test.ts | 71 - 28 files changed, 1 insertion(+), 14241 deletions(-) delete mode 100644 contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol delete mode 100644 contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol delete mode 100644 contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol delete mode 100644 contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInit.sol delete mode 100644 contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInitAbstract.sol delete mode 100644 contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol delete mode 100644 contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol delete mode 100644 contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol delete mode 100644 contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721MintableInit.sol delete mode 100644 contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721MintableInitAbstract.sol delete mode 100644 contracts/Mocks/Tokens/LSP7CompatibleERC20InitTester.sol delete mode 100644 contracts/Mocks/Tokens/LSP7CompatibleERC20Tester.sol delete mode 100644 contracts/Mocks/Tokens/LSP8CompatibleERC721Tester.sol delete mode 100644 contracts/Mocks/Tokens/LSP8CompatibleERC721TesterInit.sol delete mode 100644 docs/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.md delete mode 100644 docs/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.md delete mode 100644 docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.md delete mode 100644 docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.md delete mode 100644 tests/LSP7DigitalAsset/LSP7CompatibleERC20.behaviour.ts delete mode 100644 tests/LSP7DigitalAsset/proxy/LSP7CompatibleERC20Init.test.ts delete mode 100644 tests/LSP7DigitalAsset/standard/LSP7CompatibleERC20.test.ts delete mode 100644 tests/LSP8IdentifiableDigitalAsset/LSP8CompatibleERC721.behaviour.ts delete mode 100644 tests/LSP8IdentifiableDigitalAsset/proxy/LSP8CompatibleERC721Init.test.ts delete mode 100644 tests/LSP8IdentifiableDigitalAsset/standard/LSP8CompatibleERC721.test.ts diff --git a/.github/workflows/solc_version.yml b/.github/workflows/solc_version.yml index ee936f4ed..4aad0e860 100644 --- a/.github/workflows/solc_version.yml +++ b/.github/workflows/solc_version.yml @@ -76,7 +76,7 @@ jobs: run: | if [[ "<" == "${{ steps.comparison.outputs.comparison-result }}" ]] then - solc $(ls contracts/**/*.sol | grep -v "Compatible\|Extension4337\|contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset") \ + solc $(ls contracts/**/*.sol | grep -v "Extension4337\|contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset") \ --allow-paths $(pwd)/node_modules/ \ @=node_modules/@ \ solidity-bytes-utils/=node_modules/solidity-bytes-utils/ \ diff --git a/.mythx.yml b/.mythx.yml index 2469541ca..ce2c2cb35 100644 --- a/.mythx.yml +++ b/.mythx.yml @@ -28,16 +28,12 @@ analyze: - contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol - contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol - contracts/LSP7DigitalAsset/presets/LSP7Mintable.sol - - contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol - contracts/LSP7DigitalAsset/extensions/LSP7Burnable.sol - contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.sol - - contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol - contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.sol - contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol - - contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol - contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Burnable.sol - contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.sol - - contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol - contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.sol # - Vault & Social Recovery - contracts/LSP9Vault/LSP9Vault.sol @@ -52,13 +48,9 @@ analyze: # - Tokens & NFTs - contracts/LSP7DigitalAsset/LSP7DigitalAssetInitAbstract.sol - contracts/LSP7DigitalAsset/presets/LSP7MintableInit.sol - - contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInit.sol - - contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol - contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetInitAbstract.sol - contracts/LSP8IdentifiableDigitalAsset/presets/LSP8MintableInit.sol - - contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721MintableInit.sol - contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupplyInitAbstract.sol - - contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol - contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8EnumerableInitAbstract.sol # - Vault & Social Recovery - contracts/LSP9Vault/LSP9VaultInit.sol diff --git a/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol b/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol deleted file mode 100644 index e07bdbbe8..000000000 --- a/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol +++ /dev/null @@ -1,260 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.7; - -// interfaces -import { - IERC20Metadata, - IERC20 -} from "@openzeppelin/contracts/interfaces/IERC20Metadata.sol"; - -// modules -import {LSP7DigitalAssetCore, LSP7DigitalAsset} from "../LSP7DigitalAsset.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 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. - * - * @param name_ The name of the token. - * @param symbol_ The symbol of the token. - * @param newOwner_ The owner of the token contract. - * @param lsp4TokenType_ The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection). - */ - constructor( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_ - ) LSP7DigitalAsset(name_, symbol_, newOwner_, lsp4TokenType_, false) {} - - /** - * @inheritdoc IERC20Metadata - * @dev Returns the name of the token. - * For compatibility with clients & tools that expect ERC20. - * - * @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 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(IERC20, LSP7DigitalAssetCore) - returns (uint256) - { - 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 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) { - return authorizedAmountFor(operator, tokenOwner); - } - - /** - * @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, - uint256 amount - ) public virtual returns (bool) { - if (amount != 0) { - authorizeOperator(operator, amount, ""); - } else { - revokeOperator(operator, false, ""); - } - - return true; - } - - /** - * @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. - */ - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual returns (bool) { - transfer(from, to, amount, true, ""); - return true; - } - - // --- Overrides - - /** - * @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. - */ - function transfer( - address to, - uint256 amount - ) public virtual override returns (bool) { - transfer(msg.sender, to, amount, true, ""); - return true; - } - - /** - * @inheritdoc LSP7DigitalAssetCore - */ - function _updateOperator( - address tokenOwner, - address operator, - uint256 amount, - bool notified, - bytes memory operatorNotificationData - ) internal virtual override { - super._updateOperator( - tokenOwner, - operator, - amount, - notified, - operatorNotificationData - ); - emit IERC20.Approval(tokenOwner, operator, amount); - } - - /** - * @custom:events - * - LSP7 {Transfer} event. - * - ERC20 {Transfer} event. - */ - function _transfer( - address from, - address to, - uint256 amount, - bool force, - bytes memory data - ) internal virtual override { - emit IERC20.Transfer(from, to, amount); - super._transfer(from, to, amount, force, data); - } - - /** - * @custom:events - * - LSP7 {Transfer} event with `address(0)` as `from`. - * - ERC20 {Transfer} event with `address(0)` as `from`. - */ - function _mint( - address to, - uint256 amount, - bool force, - bytes memory data - ) internal virtual override { - emit IERC20.Transfer(address(0), to, amount); - super._mint(to, amount, force, data); - } - - /** - * @custom:events - * - LSP7 {Transfer} event with `address(0)` as the `to` address. - * - ERC20 {Transfer} event with `address(0)` as the `to` address. - */ - function _burn( - address from, - uint256 amount, - bytes memory data - ) internal virtual override { - emit IERC20.Transfer(from, address(0), amount); - super._burn(from, amount, data); - } -} diff --git a/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol b/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol deleted file mode 100644 index b97ab39aa..000000000 --- a/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol +++ /dev/null @@ -1,273 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.7; - -// interfaces -import { - IERC20Metadata, - IERC20 -} from "@openzeppelin/contracts/interfaces/IERC20Metadata.sol"; - -// modules -import { - 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 - IERC20Metadata, - LSP7DigitalAssetInitAbstract -{ - /** - * @notice Initializing a `LSP7CompatibleERC20` token contract with: token name = `name_`, token symbol = `symbol_`, and - * address `newOwner_` as the token contract owner. - * - * @param name_ The name of the token. - * @param symbol_ The symbol of the token. - * @param newOwner_ The owner of the token. - * @param lsp4TokenType_ The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection). - */ - function _initialize( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_ - ) internal virtual override onlyInitializing { - LSP7DigitalAssetInitAbstract._initialize( - name_, - symbol_, - newOwner_, - lsp4TokenType_, - false - ); - } - - /** - * @inheritdoc IERC20Metadata - * @dev Returns the name of the token. - * For compatibility with clients & tools that expect ERC20. - * - * @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 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(IERC20, LSP7DigitalAssetCore) - returns (uint256) - { - return super.balanceOf(tokenOwner); - } - - /** - * @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 override returns (uint256) { - return authorizedAmountFor(operator, tokenOwner); - } - - /** - * @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, - uint256 amount - ) public virtual returns (bool) { - if (amount != 0) { - authorizeOperator(operator, amount, ""); - } else { - revokeOperator(operator, false, ""); - } - return true; - } - - /** - * @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. - */ - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual returns (bool) { - transfer(from, to, amount, true, ""); - return true; - } - - // --- Overrides - - /** - * @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. - */ - function transfer( - address to, - uint256 amount - ) public virtual override returns (bool) { - transfer(msg.sender, to, amount, true, ""); - return true; - } - - /** - * @inheritdoc LSP7DigitalAssetCore - */ - function _updateOperator( - address tokenOwner, - address operator, - uint256 amount, - bool notified, - bytes memory operatorNotificationData - ) internal virtual override { - super._updateOperator( - tokenOwner, - operator, - amount, - notified, - operatorNotificationData - ); - emit IERC20.Approval(tokenOwner, operator, amount); - } - - /** - * @custom:events - * - LSP7 {Transfer} event. - * - ERC20 {Transfer} event. - */ - function _transfer( - address from, - address to, - uint256 amount, - bool force, - bytes memory data - ) internal virtual override { - emit IERC20.Transfer(from, to, amount); - super._transfer(from, to, amount, force, data); - } - - /** - * @custom:events - * - LSP7 {Transfer} event with `address(0)` as `from`. - * - ERC20 {Transfer} event with `address(0)` as `from`. - */ - function _mint( - address to, - uint256 amount, - bool force, - bytes memory data - ) internal virtual override { - emit IERC20.Transfer(address(0), to, amount); - super._mint(to, amount, force, data); - } - - /** - * @custom:events - * - LSP7 {Transfer} event with `address(0)` as the `to` address. - * - ERC20 {Transfer} event with `address(0)` as the `to` address. - */ - function _burn( - address from, - uint256 amount, - bytes memory data - ) internal virtual override { - emit IERC20.Transfer(from, address(0), amount); - super._burn(from, amount, data); - } -} diff --git a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol b/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol deleted file mode 100644 index 4d1bfd865..000000000 --- a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.7; - -import {LSP7CompatibleERC20} from "../extensions/LSP7CompatibleERC20.sol"; - -/** - * @title LSP7CompatibleERC20 deployable preset contract with a public {mint} function callable only by the contract {owner}. - */ -contract LSP7CompatibleERC20Mintable is LSP7CompatibleERC20 { - /** - * @notice Deploying a `LSP7CompatibleERC20Mintable` token contract with: token name = `name_`, token symbol = `symbol_`, and - * address `newOwner_` as the token contract owner. - * - * @param name_ The name of the token. - * @param symbol_ The symbol of the token. - * @param newOwner_ The owner of the token contract. - * @param lsp4TokenType_ The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection). - */ - constructor( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_ - ) LSP7CompatibleERC20(name_, symbol_, newOwner_, lsp4TokenType_) {} - - /** - * @dev Public {_mint} function only callable by the {owner}. - */ - function mint( - address to, - uint256 amount, - bool force, - bytes memory data - ) public virtual onlyOwner { - _mint(to, amount, force, data); - } -} diff --git a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInit.sol b/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInit.sol deleted file mode 100644 index d0116fa01..000000000 --- a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInit.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.7; - -// modules -import { - LSP7CompatibleERC20MintableInitAbstract -} from "./LSP7CompatibleERC20MintableInitAbstract.sol"; - -/** - * @title LSP7 deployable preset contract (proxy version) with a public mint function callable only by the contract {owner} - */ -contract LSP7CompatibleERC20MintableInit is - LSP7CompatibleERC20MintableInitAbstract -{ - /** - * @dev initialize (= lock) base implementation contract on deployment - */ - constructor() { - _disableInitializers(); - } - - /** - * @notice Initializing a `LSP7CompatibleERC20MintableInit` token contract with: token name = `name_`, token symbol = `symbol_`, and - * address `newOwner_` as the token contract owner. - * - * @param name_ The name of the token. - * @param symbol_ The symbol of the token. - * @param newOwner_ The owner of the token contract. - * @param lsp4TokenType_ The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection). - */ - function initialize( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_ - ) external virtual initializer { - LSP7CompatibleERC20MintableInitAbstract._initialize( - name_, - symbol_, - newOwner_, - lsp4TokenType_ - ); - } -} diff --git a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInitAbstract.sol b/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInitAbstract.sol deleted file mode 100644 index ca390db9a..000000000 --- a/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20MintableInitAbstract.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.7; - -// modules -import { - LSP7CompatibleERC20InitAbstract -} from "../extensions/LSP7CompatibleERC20InitAbstract.sol"; - -/** - * @title LSP7 preset contract (inheritable proxy version) with a public mint function callable only by the contract {owner} - */ -abstract contract LSP7CompatibleERC20MintableInitAbstract is - LSP7CompatibleERC20InitAbstract -{ - /** - * @inheritdoc LSP7CompatibleERC20InitAbstract - */ - function _initialize( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_ - ) internal virtual override onlyInitializing { - LSP7CompatibleERC20InitAbstract._initialize( - name_, - symbol_, - newOwner_, - lsp4TokenType_ - ); - } - - /** - * @dev Public {_mint} function only callable by the {owner}. - */ - function mint( - address to, - uint256 amount, - bool force, - bytes memory data - ) public virtual onlyOwner { - _mint(to, amount, force, data); - } -} diff --git a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol b/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol deleted file mode 100644 index 9a140cd0c..000000000 --- a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol +++ /dev/null @@ -1,512 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.12; - -// interfaces -import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import { - IERC721Receiver -} from "@openzeppelin/contracts/interfaces/IERC721Receiver.sol"; -import { - IERC721Metadata, - IERC721 -} from "@openzeppelin/contracts/interfaces/IERC721Metadata.sol"; - -// libraries -import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; -import { - EnumerableSet -} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import {LSP1Utils} from "../../LSP1UniversalReceiver/LSP1Utils.sol"; - -// modules -import { - LSP8IdentifiableDigitalAssetCore, - LSP8IdentifiableDigitalAsset -} from "../LSP8IdentifiableDigitalAsset.sol"; - -// errors -import { - LSP8NotTokenOwner, - LSP8CannotUseAddressZeroAsOperator, - LSP8TokenOwnerCannotBeOperator, - LSP8OperatorAlreadyAuthorized, - LSP8NotTokenOperator -} from "../LSP8Errors.sol"; - -// constants -import { - _LSP4_METADATA_KEY, - _LSP4_TOKEN_NAME_KEY, - _LSP4_TOKEN_SYMBOL_KEY -} from "../../LSP4DigitalAssetMetadata/LSP4Constants.sol"; -import {_TYPEID_LSP8_TOKENOPERATOR} from "../LSP8Constants.sol"; - -/** - * @dev LSP8 extension, for compatibility for clients / tools that expect ERC721. - */ -abstract contract LSP8CompatibleERC721 is - IERC721Metadata, - LSP8IdentifiableDigitalAsset -{ - using BytesLib for bytes; - using EnumerableSet for EnumerableSet.AddressSet; - using LSP1Utils for address; - - /** - * @dev Mapping from owner to operator approvals for backward compatibility with ERC721 - */ - mapping(address => mapping(address => bool)) private _operatorApprovals; - - /** - * @notice Deploying a `LSP8CompatibleERC721` token contract with: token name = `name_`, token symbol = `symbol_`, and - * address `newOwner_` as the token contract owner. - * - * @param name_ The name of the token. - * @param symbol_ The symbol of the token. - * @param newOwner_ The owner of the token contract. - * @param lsp4TokenType_ The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection). - * @param lsp8TokenIdFormat_ The format of tokenIds (= NFTs) that this contract will create. - */ - constructor( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_, - uint256 lsp8TokenIdFormat_ - ) - LSP8IdentifiableDigitalAsset( - name_, - symbol_, - newOwner_, - lsp4TokenType_, - lsp8TokenIdFormat_ - ) - {} - - /** - * @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 - */ - function supportsInterface( - bytes4 interfaceId - ) - public - view - virtual - override(IERC165, LSP8IdentifiableDigitalAsset) - returns (bool) - { - return - interfaceId == type(IERC721).interfaceId || - interfaceId == type(IERC721Metadata).interfaceId || - super.supportsInterface(interfaceId); - } - - /** - * @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) { - bytes memory data = _getData(_LSP4_METADATA_KEY); - - // offset = bytes4(hashSig) + bytes32(contentHash) -> 4 + 32 = 36 - uint256 offset = 36; - - bytes memory uriBytes = data.slice(offset, data.length - offset); - return string(uriBytes); - } - - /** - * @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 override returns (address) { - return tokenOwnerOf(bytes32(tokenId)); - } - - /** - * @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 override returns (address) { - bytes32 tokenIdAsBytes32 = bytes32(tokenId); - _existsOrError(tokenIdAsBytes32); - - address[] memory operatorsForTokenId = getOperatorsOf(tokenIdAsBytes32); - uint256 operatorListLength = operatorsForTokenId.length; - - if (operatorListLength == 0) { - return address(0); - } else { - // Read the last added operator authorized to provide "best" compatibility. - // In ERC721 there is one operator address at a time for a tokenId, so multiple calls to - // `approve` would cause `getApproved` to return the last added operator. In this - // compatibility version the same is true, when the authorized operators were not previously - // authorized. If addresses are removed, then `getApproved` returned address can change due - // to implementation of `EnumberableSet._remove`. - return operatorsForTokenId[operatorListLength - 1]; - } - } - - /** - * @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 override returns (bool) { - return _operatorApprovals[tokenOwner][operator]; - } - - /** - * @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 override { - authorizeOperator(operator, bytes32(tokenId), ""); - } - - /** - * @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 override { - _setApprovalForAll(msg.sender, operator, approved); - } - - /** - * @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`. - */ - function transferFrom( - address from, - address to, - uint256 tokenId - ) public virtual override { - _transfer(from, to, bytes32(tokenId), true, ""); - } - - /** - * @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`. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId - ) public virtual override { - _safeTransfer(from, to, tokenId, ""); - } - - /** - * @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`. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes memory data - ) public virtual override { - _safeTransfer(from, to, tokenId, data); - } - - // --- Overrides - - /** - * @inheritdoc LSP8IdentifiableDigitalAssetCore - * - * @custom:events - * - LSP7 {OperatorAuthorizationChanged} event. - * - ERC721 {Approval} event. - */ - function authorizeOperator( - address operator, - bytes32 tokenId, - bytes memory operatorNotificationData - ) public virtual override { - address tokenOwner = tokenOwnerOf(tokenId); - - if ( - tokenOwner != msg.sender && - !isApprovedForAll(tokenOwner, msg.sender) - ) { - revert LSP8NotTokenOwner(tokenOwner, tokenId, msg.sender); - } - - if (operator == address(0)) { - revert LSP8CannotUseAddressZeroAsOperator(); - } - - if (tokenOwner == operator) { - revert LSP8TokenOwnerCannotBeOperator(); - } - - bool isAdded = _operators[tokenId].add(operator); - if (!isAdded) revert LSP8OperatorAlreadyAuthorized(operator, tokenId); - - emit OperatorAuthorizationChanged( - operator, - tokenOwner, - tokenId, - operatorNotificationData - ); - emit Approval(tokenOwnerOf(tokenId), operator, uint256(tokenId)); - - bytes memory lsp1Data = abi.encode( - msg.sender, - tokenId, - operatorNotificationData - ); - operator.notifyUniversalReceiver(_TYPEID_LSP8_TOKENOPERATOR, lsp1Data); - } - - /** - * @inheritdoc LSP8IdentifiableDigitalAssetCore - * - * @custom:events - * - LSP8 {Transfer} event. - * - ERC721 {Transfer} event. - */ - function _transfer( - address from, - address to, - bytes32 tokenId, - bool force, - bytes memory data - ) internal virtual override { - if ( - !isApprovedForAll(from, msg.sender) && - !_isOperatorOrOwner(msg.sender, tokenId) - ) { - revert LSP8NotTokenOperator(tokenId, msg.sender); - } - - emit Transfer(from, to, uint256(tokenId)); - super._transfer(from, to, tokenId, force, data); - } - - /** - * @dev Transfer the `tokenId` from `from` to `to` and check if the `to` recipient address is - * a contract that implements the `IERC721Received` interface and return the right magic value. - * See {_checkOnERC721Received} for more infos. - */ - function _safeTransfer( - address from, - address to, - uint256 tokenId, - bytes memory data - ) internal virtual { - _transfer(from, to, bytes32(tokenId), true, data); - require( - _checkOnERC721Received(from, to, tokenId, data), - "LSP8CompatibleERC721: transfer to non ERC721Receiver implementer" - ); - } - - /** - * @inheritdoc LSP8IdentifiableDigitalAssetCore - * - * @custom:events - * - LSP8 {Transfer} event with `address(0)` as `from`. - * - ERC721 {Transfer} event with `address(0)` as `from`. - */ - function _mint( - address to, - bytes32 tokenId, - bool force, - bytes memory data - ) internal virtual override { - emit Transfer(address(0), to, uint256(tokenId)); - super._mint(to, tokenId, force, data); - } - - /** - * @inheritdoc LSP8IdentifiableDigitalAssetCore - * - * @custom:events - * - LSP8 {Transfer} event with `address(0)` as the `to` address. - * - ERC721 {Transfer} event with `address(0)` as the `to` address. - */ - function _burn( - bytes32 tokenId, - bytes memory data - ) internal virtual override { - address tokenOwner = tokenOwnerOf(tokenId); - - emit Transfer(tokenOwner, address(0), uint256(tokenId)); - super._burn(tokenId, data); - } - - /** - * @dev Approve `operator` to operate on all tokens of `tokensOwner`. - * - * @custom:events {ApprovalForAll} event. - */ - function _setApprovalForAll( - address tokensOwner, - address operator, - bool approved - ) internal virtual { - require( - tokensOwner != operator, - "LSP8CompatibleERC721: approve to caller" - ); - _operatorApprovals[tokensOwner][operator] = approved; - emit ApprovalForAll(tokensOwner, operator, approved); - } - - /** - * @dev Internal function to invoke `IERC721Receiver.onERC721Received(...)` function on a target address. - * The call is not executed if the target address is not a contract. - * - * @param from address representing the previous owner of the given `tokenId`. - * @param to target address that will receive the token. - * @param tokenId uint256 ID of the token to be transferred. - * @param data bytes optional data to send along with the call. - * @return bool whether the call correctly returned the expected magic value. - */ - function _checkOnERC721Received( - address from, - address to, - uint256 tokenId, - bytes memory data - ) private returns (bool) { - if (to.code.length == 0) { - return true; - } - - try - IERC721Receiver(to).onERC721Received( - msg.sender, - from, - tokenId, - data - ) - returns (bytes4 retval) { - return retval == IERC721Receiver.onERC721Received.selector; - } catch (bytes memory reason) { - if (reason.length == 0) { - revert( - "LSP8CompatibleERC721: transfer to non ERC721Receiver implementer" - ); - } else { - // solhint-disable no-inline-assembly - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } -} diff --git a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol b/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol deleted file mode 100644 index 3a685f0d9..000000000 --- a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol +++ /dev/null @@ -1,514 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.12; - -// interfaces -import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol"; -import { - IERC721Receiver -} from "@openzeppelin/contracts/interfaces/IERC721Receiver.sol"; -import { - IERC721Metadata, - IERC721 -} from "@openzeppelin/contracts/interfaces/IERC721Metadata.sol"; - -// libraries -import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; -import { - EnumerableSet -} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import {LSP1Utils} from "../../LSP1UniversalReceiver/LSP1Utils.sol"; - -// modules -import { - LSP8IdentifiableDigitalAssetCore, - LSP8IdentifiableDigitalAssetInitAbstract -} from "../LSP8IdentifiableDigitalAssetInitAbstract.sol"; - -// errors -import { - LSP8NotTokenOwner, - LSP8CannotUseAddressZeroAsOperator, - LSP8TokenOwnerCannotBeOperator, - LSP8OperatorAlreadyAuthorized, - LSP8NotTokenOperator -} from "../LSP8Errors.sol"; - -// constants -import { - _LSP4_METADATA_KEY, - _LSP4_TOKEN_NAME_KEY, - _LSP4_TOKEN_SYMBOL_KEY -} from "../../LSP4DigitalAssetMetadata/LSP4Constants.sol"; -import {_TYPEID_LSP8_TOKENOPERATOR} from "../LSP8Constants.sol"; - -/** - * @dev LSP8 extension, for compatibility for clients / tools that expect ERC721. - */ -abstract contract LSP8CompatibleERC721InitAbstract is - IERC721Metadata, - LSP8IdentifiableDigitalAssetInitAbstract -{ - using BytesLib for bytes; - using EnumerableSet for EnumerableSet.AddressSet; - using LSP1Utils for address; - - /** - * @dev Mapping from owner to operator approvals for backward compatibility with ERC721 - */ - mapping(address => mapping(address => bool)) private _operatorApprovals; - - /** - * @notice Initialize a `LSP8CompatibleERC721InitAbstract` token contract with: token name = `name_`, token symbol = `symbol_`, and - * address `newOwner_` as the token contract owner. - * - * @param name_ The name of the token. - * @param symbol_ The symbol of the token. - * @param newOwner_ The owner of the token contract. - * @param lsp4TokenType_ The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection). - * @param lsp8TokenIdFormat_ The format of tokenIds (= NFTs) that this contract will create. - */ - - function _initialize( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_, - uint256 lsp8TokenIdFormat_ - ) internal virtual override onlyInitializing { - LSP8IdentifiableDigitalAssetInitAbstract._initialize( - name_, - symbol_, - newOwner_, - lsp4TokenType_, - lsp8TokenIdFormat_ - ); - } - - /** - * @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 - */ - function supportsInterface( - bytes4 interfaceId - ) - public - view - virtual - override(IERC165, LSP8IdentifiableDigitalAssetInitAbstract) - returns (bool) - { - return - interfaceId == type(IERC721).interfaceId || - interfaceId == type(IERC721Metadata).interfaceId || - super.supportsInterface(interfaceId); - } - - /** - * @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 override returns (string memory) { - bytes memory data = _getData(_LSP4_METADATA_KEY); - - // offset = bytes4(hashSig) + bytes32(contentHash) -> 4 + 32 = 36 - uint256 offset = 36; - - bytes memory uriBytes = data.slice(offset, data.length - offset); - return string(uriBytes); - } - - /** - * @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 override returns (address) { - return tokenOwnerOf(bytes32(tokenId)); - } - - /** - * @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 override returns (address) { - bytes32 tokenIdAsBytes32 = bytes32(tokenId); - _existsOrError(tokenIdAsBytes32); - - address[] memory operatorsForTokenId = getOperatorsOf(tokenIdAsBytes32); - uint256 operatorListLength = operatorsForTokenId.length; - - if (operatorListLength == 0) { - return address(0); - } else { - // Read the last added operator authorized to provide "best" compatibility. - // In ERC721 there is one operator address at a time for a tokenId, so multiple calls to - // `approve` would cause `getApproved` to return the last added operator. In this - // compatibility version the same is true, when the authorized operators were not previously - // authorized. If addresses are removed, then `getApproved` returned address can change due - // to implementation of `EnumberableSet._remove`. - return operatorsForTokenId[operatorListLength - 1]; - } - } - - /** - * @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 override returns (bool) { - return _operatorApprovals[tokenOwner][operator]; - } - - /** - * @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 override { - authorizeOperator(operator, bytes32(tokenId), ""); - emit Approval(tokenOwnerOf(bytes32(tokenId)), operator, tokenId); - } - - /** - * @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 override { - _setApprovalForAll(msg.sender, operator, approved); - } - - /** - * @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`. - */ - function transferFrom( - address from, - address to, - uint256 tokenId - ) public virtual override { - _transfer(from, to, bytes32(tokenId), true, ""); - } - - /** - * @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`. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId - ) public virtual override { - _safeTransfer(from, to, tokenId, ""); - } - - /** - * @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`. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes memory data - ) public virtual override { - _safeTransfer(from, to, tokenId, data); - } - - // --- Overrides - - /** - * @inheritdoc LSP8IdentifiableDigitalAssetCore - * - * @custom:events - * - LSP7 {OperatorAuthorizationChanged} event. - * - ERC721 {Approval} event. - */ - function authorizeOperator( - address operator, - bytes32 tokenId, - bytes memory operatorNotificationData - ) public virtual override { - address tokenOwner = tokenOwnerOf(tokenId); - - if ( - tokenOwner != msg.sender && - !isApprovedForAll(tokenOwner, msg.sender) - ) { - revert LSP8NotTokenOwner(tokenOwner, tokenId, msg.sender); - } - - if (operator == address(0)) { - revert LSP8CannotUseAddressZeroAsOperator(); - } - - if (tokenOwner == operator) { - revert LSP8TokenOwnerCannotBeOperator(); - } - - bool isAdded = _operators[tokenId].add(operator); - if (!isAdded) revert LSP8OperatorAlreadyAuthorized(operator, tokenId); - - emit OperatorAuthorizationChanged( - operator, - tokenOwner, - tokenId, - operatorNotificationData - ); - emit Approval(tokenOwnerOf(tokenId), operator, uint256(tokenId)); - - bytes memory lsp1Data = abi.encode( - msg.sender, - tokenId, - operatorNotificationData - ); - operator.notifyUniversalReceiver(_TYPEID_LSP8_TOKENOPERATOR, lsp1Data); - } - - /** - * @inheritdoc LSP8IdentifiableDigitalAssetCore - * - * @custom:events - * - LSP8 {Transfer} event. - * - ERC721 {Transfer} event. - */ - function _transfer( - address from, - address to, - bytes32 tokenId, - bool force, - bytes memory data - ) internal virtual override { - if ( - !isApprovedForAll(from, msg.sender) && - !_isOperatorOrOwner(msg.sender, tokenId) - ) { - revert LSP8NotTokenOperator(tokenId, msg.sender); - } - - emit Transfer(from, to, uint256(tokenId)); - super._transfer(from, to, tokenId, force, data); - } - - /** - * @dev Transfer the `tokenId` from `from` to `to` and check if the `to` recipient address is - * a contract that implements the `IERC721Received` interface and return the right magic value. - * See {_checkOnERC721Received} for more infos. - */ - function _safeTransfer( - address from, - address to, - uint256 tokenId, - bytes memory data - ) internal virtual { - _transfer(from, to, bytes32(tokenId), true, data); - require( - _checkOnERC721Received(from, to, tokenId, data), - "LSP8CompatibleERC721: transfer to non ERC721Receiver implementer" - ); - } - - /** - * @inheritdoc LSP8IdentifiableDigitalAssetCore - * - * @custom:events - * - LSP8 {Transfer} event with `address(0)` as `from`. - * - ERC721 {Transfer} event with `address(0)` as `from`. - */ - function _mint( - address to, - bytes32 tokenId, - bool force, - bytes memory data - ) internal virtual override { - emit Transfer(address(0), to, uint256(tokenId)); - super._mint(to, tokenId, force, data); - } - - /** - * @inheritdoc LSP8IdentifiableDigitalAssetCore - * - * @custom:events - * - LSP8 {Transfer} event with `address(0)` as the `to` address. - * - ERC721 {Transfer} event with `address(0)` as the `to` address. - */ - function _burn( - bytes32 tokenId, - bytes memory data - ) internal virtual override { - address tokenOwner = tokenOwnerOf(tokenId); - - emit Transfer(tokenOwner, address(0), uint256(tokenId)); - super._burn(tokenId, data); - } - - /** - * @dev Approve `operator` to operate on all tokens of `tokensOwner`. - * - * @custom:events {ApprovalForAll} event. - */ - function _setApprovalForAll( - address tokensOwner, - address operator, - bool approved - ) internal virtual { - require( - tokensOwner != operator, - "LSP8CompatibleERC721: approve to caller" - ); - _operatorApprovals[tokensOwner][operator] = approved; - emit ApprovalForAll(tokensOwner, operator, approved); - } - - /** - * @dev Internal function to invoke `IERC721Receiver.onERC721Received(...)` function on a target address. - * The call is not executed if the target address is not a contract. - * - * @param from address representing the previous owner of the given `tokenId`. - * @param to target address that will receive the token. - * @param tokenId uint256 ID of the token to be transferred. - * @param data bytes optional data to send along with the call. - * @return bool whether the call correctly returned the expected magic value. - */ - function _checkOnERC721Received( - address from, - address to, - uint256 tokenId, - bytes memory data - ) private returns (bool) { - if (to.code.length == 0) { - return true; - } - - try - IERC721Receiver(to).onERC721Received( - msg.sender, - from, - tokenId, - data - ) - returns (bytes4 retval) { - return retval == IERC721Receiver.onERC721Received.selector; - } catch (bytes memory reason) { - if (reason.length == 0) { - revert( - "LSP8CompatibleERC721: transfer to non ERC721Receiver implementer" - ); - } else { - // solhint-disable no-inline-assembly - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } -} diff --git a/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol b/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol deleted file mode 100644 index 981ee1a61..000000000 --- a/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.12; - -import {LSP8CompatibleERC721} from "../extensions/LSP8CompatibleERC721.sol"; - -/** - * @title LSP8CompatibleERC721Mintable deployable preset contract with a public {mint} function callable only by the contract {owner}. - */ -contract LSP8CompatibleERC721Mintable is LSP8CompatibleERC721 { - /** - * @notice Deploying a `LSP8CompatibleERC721Mintable` token contract with: token name = `name_`, token symbol = `symbol_`, and - * address `newOwner_` as the token contract owner. - * - * @param name_ The name of the token. - * @param symbol_ The symbol of the token. - * @param newOwner_ The owner of the token contract. - * @param lsp4TokenType_ The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection). - * @param lsp8TokenIdFormat_ The format of tokenIds (= NFTs) that this contract will create. - */ - constructor( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_, - uint256 lsp8TokenIdFormat_ - ) - LSP8CompatibleERC721( - name_, - symbol_, - newOwner_, - lsp4TokenType_, - lsp8TokenIdFormat_ - ) - {} - - /** - * @notice Minting tokenId `tokenId` for address `to` with the additional data `data` (Note: allow non-LSP1 recipient is set to `force`). - * - * @dev Public {_mint} function only callable by the {owner}. - * - * @param to The address that will receive the minted `tokenId`. - * @param tokenId The tokenId to mint. - * @param force Set to `false` to ensure that you are minting for a recipient that implements LSP1, `false` otherwise for forcing the minting. - * @param data Any addition data to be sent alongside the minting. - */ - function mint( - address to, - bytes32 tokenId, - bool force, - bytes memory data - ) public virtual onlyOwner { - _mint(to, tokenId, force, data); - } -} diff --git a/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721MintableInit.sol b/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721MintableInit.sol deleted file mode 100644 index 9f82cdbf1..000000000 --- a/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721MintableInit.sol +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.12; - -// modules -import { - LSP8CompatibleERC721MintableInitAbstract -} from "./LSP8CompatibleERC721MintableInitAbstract.sol"; - -/** - * @title LSP8CompatibleERC721MintableInit deployable preset contract (proxy version) with a public mint function callable only by the contract {owner} - */ -contract LSP8CompatibleERC721MintableInit is - LSP8CompatibleERC721MintableInitAbstract -{ - /** - * @dev initialize (= lock) base implementation contract on deployment - */ - constructor() { - _disableInitializers(); - } - - /** - * @notice Initializing a `LSP8CompatibleERC721MintableInit` token contract with: token name = `name_`, token symbol = `symbol_`, and - * address `newOwner_` as the token contract owner. - * - * @param name_ The name of the token. - * @param symbol_ The symbol of the token. - * @param newOwner_ The owner of the token contract. - * @param lsp4TokenType_ The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection). - * @param lsp8TokenIdFormat_ The format of tokenIds (= NFTs) that this contract will create. - */ - function initialize( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_, - uint256 lsp8TokenIdFormat_ - ) external virtual initializer { - LSP8CompatibleERC721MintableInitAbstract._initialize( - name_, - symbol_, - newOwner_, - lsp4TokenType_, - lsp8TokenIdFormat_ - ); - } -} diff --git a/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721MintableInitAbstract.sol b/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721MintableInitAbstract.sol deleted file mode 100644 index 462e52d9b..000000000 --- a/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721MintableInitAbstract.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.12; - -// modules -import { - LSP8CompatibleERC721InitAbstract -} from "../extensions/LSP8CompatibleERC721InitAbstract.sol"; - -/** - * @title LSP8CompatibleERC721MintableInitAbstract preset contract (inheritable proxy version) with a public mint function callable only by the contract {owner} - */ -contract LSP8CompatibleERC721MintableInitAbstract is - LSP8CompatibleERC721InitAbstract -{ - /** - * @inheritdoc LSP8CompatibleERC721InitAbstract - */ - function _initialize( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_, - uint256 lsp8TokenIdFormat_ - ) internal virtual override onlyInitializing { - LSP8CompatibleERC721InitAbstract._initialize( - name_, - symbol_, - newOwner_, - lsp4TokenType_, - lsp8TokenIdFormat_ - ); - } - - /** - * @notice Minting tokenId `tokenId` for address `to` with the additional data `data` (Note: allow non-LSP1 recipient is set to `force`). - * - * @dev Public {_mint} function only callable by the {owner}. - * - * @param to The address that will receive the minted `tokenId`. - * @param tokenId The tokenId to mint. - * @param force Set to `false` to ensure that you are minting for a recipient that implements LSP1, `false` otherwise for forcing the minting. - * @param data Any addition data to be sent alongside the minting. - */ - function mint( - address to, - bytes32 tokenId, - bool force, - bytes memory data - ) public virtual onlyOwner { - _mint(to, tokenId, force, data); - } -} diff --git a/contracts/Mocks/Tokens/LSP7CompatibleERC20InitTester.sol b/contracts/Mocks/Tokens/LSP7CompatibleERC20InitTester.sol deleted file mode 100644 index bf5b86e7e..000000000 --- a/contracts/Mocks/Tokens/LSP7CompatibleERC20InitTester.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.8.4; - -// modules -import { - LSP7CompatibleERC20InitAbstract -} from "../../LSP7DigitalAsset/extensions/LSP7CompatibleERC20InitAbstract.sol"; - -contract LSP7CompatibleERC20InitTester is LSP7CompatibleERC20InitAbstract { - /** - * @dev initialize (= lock) base implementation contract on deployment - */ - constructor() { - _disableInitializers(); - } - - function initialize( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_ - ) public initializer { - LSP7CompatibleERC20InitAbstract._initialize( - name_, - symbol_, - newOwner_, - lsp4TokenType_ - ); - } - - function mint(address to, uint256 amount, bytes calldata data) public { - // using force=true so we can send to EOA in test - _mint(to, amount, true, data); - } - - function burn(address from, uint256 amount, bytes calldata data) public { - _burn(from, amount, data); - } -} diff --git a/contracts/Mocks/Tokens/LSP7CompatibleERC20Tester.sol b/contracts/Mocks/Tokens/LSP7CompatibleERC20Tester.sol deleted file mode 100644 index 7a2bd280b..000000000 --- a/contracts/Mocks/Tokens/LSP7CompatibleERC20Tester.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.8.4; - -// modules -import { - LSP7CompatibleERC20 -} from "../../LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol"; - -contract LSP7CompatibleERC20Tester is LSP7CompatibleERC20 { - constructor( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_ - ) LSP7CompatibleERC20(name_, symbol_, newOwner_, lsp4TokenType_) {} - - function mint(address to, uint256 amount, bytes calldata data) public { - // using force=true so we can send to EOA in test - _mint(to, amount, true, data); - } - - function burn(address from, uint256 amount, bytes calldata data) public { - _burn(from, amount, data); - } -} diff --git a/contracts/Mocks/Tokens/LSP8CompatibleERC721Tester.sol b/contracts/Mocks/Tokens/LSP8CompatibleERC721Tester.sol deleted file mode 100644 index 29e32729e..000000000 --- a/contracts/Mocks/Tokens/LSP8CompatibleERC721Tester.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.8.4; - -// modules -import { - LSP8CompatibleERC721 -} from "../../LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol"; - -// constants -import { - _LSP4_METADATA_KEY -} from "../../LSP4DigitalAssetMetadata/LSP4Constants.sol"; - -contract LSP8CompatibleERC721Tester is LSP8CompatibleERC721 { - constructor( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_, - uint256 lsp8TokenIdFormat_, - bytes memory tokenURIValue_ - ) - LSP8CompatibleERC721( - name_, - symbol_, - newOwner_, - lsp4TokenType_, - lsp8TokenIdFormat_ - ) - { - _setData(_LSP4_METADATA_KEY, tokenURIValue_); - } - - function mint(address to, uint256 tokenId, bytes calldata data) public { - // using force=true so we can send to EOA in test - _mint(to, bytes32(tokenId), true, data); - } - - function burn(uint256 tokenId, bytes calldata data) public { - _burn(bytes32(tokenId), data); - } -} diff --git a/contracts/Mocks/Tokens/LSP8CompatibleERC721TesterInit.sol b/contracts/Mocks/Tokens/LSP8CompatibleERC721TesterInit.sol deleted file mode 100644 index ddcab4dfd..000000000 --- a/contracts/Mocks/Tokens/LSP8CompatibleERC721TesterInit.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.8.4; - -// modules -import { - LSP8CompatibleERC721InitAbstract -} from "../../LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol"; - -// constants -import { - _LSP4_METADATA_KEY -} from "../../LSP4DigitalAssetMetadata/LSP4Constants.sol"; - -contract LSP8CompatibleERC721InitTester is LSP8CompatibleERC721InitAbstract { - /** - * @dev initialize (= lock) base implementation contract on deployment - */ - constructor() { - _disableInitializers(); - } - - function initialize( - string memory name_, - string memory symbol_, - address newOwner_, - uint256 lsp4TokenType_, - uint256 lsp8TokenIdFormat_, - bytes memory tokenURIValue_ - ) public virtual initializer { - LSP8CompatibleERC721InitAbstract._initialize( - name_, - symbol_, - newOwner_, - lsp4TokenType_, - lsp8TokenIdFormat_ - ); - - _setData(_LSP4_METADATA_KEY, tokenURIValue_); - } - - function mint(address to, uint256 tokenId, bytes calldata data) public { - // using force=true so we can send to EOA in test - _mint(to, bytes32(tokenId), true, data); - } - - function burn(uint256 tokenId, bytes calldata data) public { - _burn(bytes32(tokenId), data); - } -} diff --git a/docs/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.md b/docs/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.md deleted file mode 100644 index c19ca619d..000000000 --- a/docs/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.md +++ /dev/null @@ -1,1991 +0,0 @@ - - - -# LSP7CompatibleERC20 - -:::info Standard Specifications - -[`LSP-7-DigitalAsset`](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md) - -::: -:::info Solidity implementation - -[`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) - -::: - -LSP7 extension, for compatibility for clients / tools that expect ERC20. - -## 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. - -### fallback - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#fallback) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) - -::: - -```solidity -fallback(bytes calldata callData) external payable returns (bytes memory); -``` - -_The `fallback` function was called with the following amount of native tokens: `msg.value`; and the following calldata: `callData`._ - -Achieves the goal of [LSP-17-ContractExtension] standard by extending the contract to handle calls of functions that do not exist natively, -forwarding the function call to the extension address mapped to the function being called. -This function is executed when: - -- Sending data of length less than 4 bytes to the contract. - -- The first 4 bytes of the calldata do not match any publicly callable functions from the contract ABI. - -- Receiving native tokens - -1. If the data is equal or longer than 4 bytes, the [ERC-725Y] storage is queried with the following data key: [_LSP17_EXTENSION_PREFIX] + `bytes4(msg.sig)` (Check [LSP-2-ERC725YJSONSchema] for encoding the data key) - -- If there is no address stored under the following data key, revert with [`NoExtensionFoundForFunctionSelector(bytes4)`](#noextensionfoundforfunctionselector). The data key relative to `bytes4(0)` is an exception, where no reverts occurs if there is no extension address stored under. This exception is made to allow users to send random data (graffiti) to the account and to be able to react on it. - -- If there is an address, forward the `msg.data` to the extension using the CALL opcode, appending 52 bytes (20 bytes of `msg.sender` and 32 bytes of `msg.value`). Return what the calls returns, or revert if the call failed. - -2. If the data sent to this function is of length less than 4 bytes (not a function selector), revert. - -
- -### receive - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#receive) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) - -::: - -```solidity -receive() external payable; -``` - -_LSP7 contract cannot receive native tokens._ - -Reverts whenever someone tries to send native tokens to a LSP7 contract. - -
- -### allowance - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#allowance) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `allowance(address,address)` -- Function selector: `0xdd62ed3e` - -::: - -```solidity -function allowance( - address tokenOwner, - address operator -) 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` | The address of the token owner | -| `operator` | `address` | The address approved by the `tokenOwner` | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------------------------------- | -| `0` | `uint256` | The amount `operator` is approved by `tokenOwner` | - -
- -### approve - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#approve) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `approve(address,uint256)` -- Function selector: `0x095ea7b3` - -::: - -```solidity -function approve( - address operator, - uint256 amount -) external nonpayable returns (bool); -``` - -Approval function from th ERC20 standard interface. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ----------------------------------- | -| `operator` | `address` | The address to approve for `amount` | -| `amount` | `uint256` | The amount to approve. | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | ------------------------------ | -| `0` | `bool` | `true` on successful approval. | - -
- -### authorizeOperator - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#authorizeoperator) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `authorizeOperator(address,uint256,bytes)` -- Function selector: `0xb49506fd` - -::: - -:::danger - -To avoid front-running and Allowance Double-Spend Exploit when increasing or decreasing the authorized amount of an operator, it is advised to use the [`increaseAllowance`](#increaseallowance) and [`decreaseAllowance`](#decreaseallowance) functions. For more information, see: https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/ - -::: - -```solidity -function authorizeOperator( - address operator, - uint256 amount, - bytes operatorNotificationData -) external nonpayable; -``` - -Sets an `amount` of tokens that an `operator` has access from the caller's balance (allowance). See [`authorizedAmountFor`](#authorizedamountfor). Notify the operator based on the LSP1-UniversalReceiver standard - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ------------------------------------------------------ | -| `operator` | `address` | The address to authorize as an operator. | -| `amount` | `uint256` | The allowance amount of tokens operator has access to. | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### authorizedAmountFor - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#authorizedamountfor) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `authorizedAmountFor(address,address)` -- Function selector: `0x65aeaa95` - -::: - -```solidity -function authorizedAmountFor( - address operator, - address tokenOwner -) external view returns (uint256); -``` - -Get the amount of tokens `operator` address has access to from `tokenOwner`. Operators can send and burn tokens on behalf of their owners. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ---------------------------------------------------------- | -| `operator` | `address` | The operator's address to query the authorized amount for. | -| `tokenOwner` | `address` | The token owner that `operator` has allowance on. | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | --------------------------------------------------------------------------------------- | -| `0` | `uint256` | The amount of tokens the `operator`'s address has access on the `tokenOwner`'s balance. | - -
- -### balanceOf - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#balanceof) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `balanceOf(address)` -- Function selector: `0x70a08231` - -::: - -```solidity -function balanceOf(address tokenOwner) external view returns (uint256); -``` - -Get the number of tokens owned by `tokenOwner`. If the token is divisible (the [`decimals`](#decimals) function returns `18`), the amount returned should be divided by 1e18 to get a better picture of the actual balance of the `tokenOwner`. _Example:_ `balanceOf(someAddress) -> 42_000_000_000_000_000_000 / 1e18 = 42 tokens` - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | --------------------------------------------------------- | -| `tokenOwner` | `address` | The address of the token holder to query the balance for. | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------------------------- | -| `0` | `uint256` | The amount of tokens owned by `tokenOwner`. | - -
- -### batchCalls - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#batchcalls) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `batchCalls(bytes[])` -- Function selector: `0x6963d438` - -::: - -:::info - -It's not possible to send value along the functions call due to the use of `delegatecall`. - -::: - -```solidity -function batchCalls(bytes[] data) external nonpayable returns (bytes[] results); -``` - -_Executing the following batch of abi-encoded function calls on the contract: `data`._ - -Allows a caller to batch different function calls in one call. Perform a `delegatecall` on self, to call different functions with preserving the context. - -#### Parameters - -| Name | Type | Description | -| ------ | :-------: | -------------------------------------------------------------------- | -| `data` | `bytes[]` | An array of ABI encoded function calls to be called on the contract. | - -#### Returns - -| Name | Type | Description | -| --------- | :-------: | ---------------------------------------------------------------- | -| `results` | `bytes[]` | An array of abi-encoded data returned by the functions executed. | - -
- -### decimals - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#decimals) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `decimals()` -- Function selector: `0x313ce567` - -::: - -```solidity -function decimals() external view returns (uint8); -``` - -Returns the number of decimals used to get its user representation. If the asset contract has been set to be non-divisible via the `isNonDivisible_` parameter in the `constructor`, the decimals returned wiil be `0`. Otherwise `18` is the common value. - -#### Returns - -| Name | Type | Description | -| ---- | :-----: | ----------------------------------------------------------------------- | -| `0` | `uint8` | the number of decimals. If `0` is returned, the asset is non-divisible. | - -
- -### decreaseAllowance - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#decreaseallowance) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `decreaseAllowance(address,uint256,bytes)` -- Function selector: `0x7b204c4e` - -::: - -```solidity -function decreaseAllowance( - address operator, - uint256 subtractedAmount, - bytes operatorNotificationData -) external nonpayable; -``` - -_Decrease the allowance of `operator` by -`subtractedAmount`_ - -Atomically decreases the allowance granted to `operator` by the caller. This is an alternative approach to [`authorizeOperator`](#authorizeoperator) that can be used as a mitigation for the double spending allowance problem. Notify the operator based on the LSP1-UniversalReceiver standard - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ------------------------------------------------------ | -| `operator` | `address` | The operator to decrease allowance for `msg.sender` | -| `subtractedAmount` | `uint256` | The amount to decrease by in the operator's allowance. | -| `operatorNotificationData` | `bytes` | - | - -
- -### getData - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#getdata) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#getdatabatch) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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 | - -
- -### getOperatorsOf - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#getoperatorsof) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `getOperatorsOf(address)` -- Function selector: `0xd72fc29a` - -::: - -```solidity -function getOperatorsOf(address tokenOwner) external view returns (address[]); -``` - -Returns all `operator` addresses that are allowed to transfer or burn on behalf of `tokenOwner`. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ----------------------------------------- | -| `tokenOwner` | `address` | The token owner to get the operators for. | - -#### Returns - -| Name | Type | Description | -| ---- | :---------: | ----------------------------------------------------------------------------------- | -| `0` | `address[]` | An array of operators allowed to transfer or burn tokens on behalf of `tokenOwner`. | - -
- -### increaseAllowance - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#increaseallowance) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `increaseAllowance(address,uint256,bytes)` -- Function selector: `0x2bc1da82` - -::: - -```solidity -function increaseAllowance( - address operator, - uint256 addedAmount, - bytes operatorNotificationData -) external nonpayable; -``` - -_Increase the allowance of `operator` by +`addedAmount`_ - -Atomically increases the allowance granted to `operator` by the caller. This is an alternative approach to [`authorizeOperator`](#authorizeoperator) that can be used as a mitigation for the double spending allowance problem. Notify the operator based on the LSP1-UniversalReceiver standard - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ----------------------------------------------------------------------- | -| `operator` | `address` | The operator to increase the allowance for `msg.sender` | -| `addedAmount` | `uint256` | The additional amount to add on top of the current operator's allowance | -| `operatorNotificationData` | `bytes` | - | - -
- -### name - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#name) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `name()` -- Function selector: `0x06fdde03` - -::: - -```solidity -function name() external view returns (string); -``` - -Returns the name of the token. For compatibility with clients & tools that expect ERC20. - -#### Returns - -| Name | Type | Description | -| ---- | :------: | --------------------- | -| `0` | `string` | The name of the token | - -
- -### owner - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#owner) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#renounceownership) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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. - -
- -### revokeOperator - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#revokeoperator) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `revokeOperator(address,bool,bytes)` -- Function selector: `0x4521748e` - -::: - -```solidity -function revokeOperator( - address operator, - bool notify, - bytes operatorNotificationData -) external nonpayable; -``` - -Removes the `operator` address as an operator of callers tokens, disallowing it to send any amount of tokens on behalf of the token owner (the caller of the function `msg.sender`). See also [`authorizedAmountFor`](#authorizedamountfor). - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | --------------------------------------------------------- | -| `operator` | `address` | The address to revoke as an operator. | -| `notify` | `bool` | Boolean indicating whether to notify the operator or not. | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### setData - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#setdata) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#setdatabatch) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#supportsinterface) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `supportsInterface(bytes4)` -- Function selector: `0x01ffc9a7` - -::: - -```solidity -function supportsInterface(bytes4 interfaceId) external view returns (bool); -``` - -Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas. - -#### Parameters - -| Name | Type | Description | -| ------------- | :------: | ----------- | -| `interfaceId` | `bytes4` | - | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | - -
- -### symbol - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#symbol) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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. For compatibility with clients & tools that expect ERC20. - -#### Returns - -| Name | Type | Description | -| ---- | :------: | ----------------------- | -| `0` | `string` | The symbol of the token | - -
- -### totalSupply - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#totalsupply) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `totalSupply()` -- Function selector: `0x18160ddd` - -::: - -```solidity -function totalSupply() external view returns (uint256); -``` - -Returns the number of existing tokens that have been minted in this contract. - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------------ | -| `0` | `uint256` | The number of existing tokens. | - -
- -### transfer - -:::note References - -- 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) -- Function signature: `transfer(address,address,uint256,bool,bytes)` -- Function selector: `0x760d9bba` - -::: - -```solidity -function transfer( - address from, - address to, - uint256 amount, - bool force, - bytes data -) external nonpayable; -``` - -Transfers an `amount` of tokens from the `from` address to the `to` address and notify both sender and recipients via the LSP1 [`universalReceiver(...)`](#`universalreceiver) function. If the tokens are transferred by an operator on behalf of a token holder, the allowance for the operator will be decreased by `amount` once the token transfer has been completed (See [`authorizedAmountFor`](#authorizedamountfor)). - -#### Parameters - -| Name | Type | Description | -| -------- | :-------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `from` | `address` | The sender address. | -| `to` | `address` | The recipient address. | -| `amount` | `uint256` | The amount of tokens to transfer. | -| `force` | `bool` | When set to `true`, the `to` address CAN be any address. When set to `false`, the `to` address MUST be a contract that supports the LSP1 UniversalReceiver standard. | -| `data` | `bytes` | Any additional data the caller wants included in the emitted event, and sent in the hooks of the `from` and `to` addresses. | - -
- -### transfer - -:::note References - -- 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) -- Function signature: `transfer(address,uint256)` -- Function selector: `0xa9059cbb` - -::: - -:::info - -This function uses the `force` parameter as `true` so that EOA and any contract can receive tokens. - -::: - -```solidity -function transfer( - address to, - uint256 amount -) external nonpayable returns (bool); -``` - -Transfer function from the ERC20 standard interface. - -#### Parameters - -| Name | Type | Description | -| -------- | :-------: | --------------------------------- | -| `to` | `address` | The address receiving tokens. | -| `amount` | `uint256` | The amount of tokens to transfer. | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | ------------------------------ | -| `0` | `bool` | `true` on successful transfer. | - -
- -### transferBatch - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#transferbatch) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `transferBatch(address[],address[],uint256[],bool[],bytes[])` -- Function selector: `0x2d7667c9` - -::: - -```solidity -function transferBatch( - address[] from, - address[] to, - uint256[] amount, - bool[] force, - bytes[] data -) external nonpayable; -``` - -Same as [`transfer(...)`](#`transfer) but transfer multiple tokens based on the arrays of `from`, `to`, `amount`. - -#### Parameters - -| Name | Type | Description | -| -------- | :---------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `from` | `address[]` | An array of sending addresses. | -| `to` | `address[]` | An array of receiving addresses. | -| `amount` | `uint256[]` | An array of amount of tokens to transfer for each `from -> to` transfer. | -| `force` | `bool[]` | For each transfer, when set to `true`, the `to` address CAN be any address. When set to `false`, the `to` address MUST be a contract that supports the LSP1 UniversalReceiver standard. | -| `data` | `bytes[]` | An array of additional data the caller wants included in the emitted event, and sent in the hooks to `from` and `to` addresses. | - -
- -### transferFrom - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#transferfrom) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Function signature: `transferFrom(address,address,uint256)` -- Function selector: `0x23b872dd` - -::: - -:::info - -This function uses the `force` parameter as `true` so that EOA and any contract can receive tokens. - -::: - -```solidity -function transferFrom( - address from, - address to, - uint256 amount -) external nonpayable returns (bool); -``` - -Transfer functions for operators from the ERC20 standard interface. - -#### Parameters - -| 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` | `true` on successful transfer. | - -
- -### transferOwnership - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#transferownership) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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; -``` - -The ERC725Y data keys `LSP4TokenName` and `LSP4TokenSymbol` cannot be changed -via this function once the digital asset contract has been deployed. - -
- -### \_updateOperator - -```solidity -function _updateOperator( - address tokenOwner, - address operator, - uint256 amount, - bool notified, - bytes operatorNotificationData -) internal nonpayable; -``` - -
- -### \_mint - -```solidity -function _mint( - address to, - uint256 amount, - bool force, - bytes data -) internal nonpayable; -``` - -
- -### \_burn - -```solidity -function _burn(address from, uint256 amount, bytes data) internal nonpayable; -``` - -
- -### \_spendAllowance - -```solidity -function _spendAllowance( - address operator, - address tokenOwner, - uint256 amountToSpend -) internal nonpayable; -``` - -Spend `amountToSpend` from the `operator`'s authorized on behalf of the `tokenOwner`. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ------------------------------------------------------------------- | -| `operator` | `address` | The address of the operator to decrease the allowance of. | -| `tokenOwner` | `address` | The address that granted an allowance on its balance to `operator`. | -| `amountToSpend` | `uint256` | The amount of tokens to substract in allowance of `operator`. | - -
- -### \_transfer - -```solidity -function _transfer( - address from, - address to, - uint256 amount, - bool force, - bytes data -) internal nonpayable; -``` - -
- -### \_beforeTokenTransfer - -```solidity -function _beforeTokenTransfer( - address from, - address to, - uint256 amount, - bytes data -) internal nonpayable; -``` - -Hook that is called before any token transfer, including minting and burning. -Allows to run custom logic before updating balances and notifiying sender/recipient by overriding this function. - -#### Parameters - -| Name | Type | Description | -| -------- | :-------: | ------------------------------------ | -| `from` | `address` | The sender address | -| `to` | `address` | The recipient address | -| `amount` | `uint256` | The amount of token to transfer | -| `data` | `bytes` | The data sent alongside the transfer | - -
- -### \_afterTokenTransfer - -```solidity -function _afterTokenTransfer( - address from, - address to, - uint256 amount, - bytes data -) internal nonpayable; -``` - -Hook that is called after any token transfer, including minting and burning. -Allows to run custom logic after updating balances, but **before notifiying sender/recipient** by overriding this function. - -#### Parameters - -| Name | Type | Description | -| -------- | :-------: | ------------------------------------ | -| `from` | `address` | The sender address | -| `to` | `address` | The recipient address | -| `amount` | `uint256` | The amount of token to transfer | -| `data` | `bytes` | The data sent alongside the transfer | - -
- -### \_notifyTokenOperator - -```solidity -function _notifyTokenOperator( - address operator, - bytes lsp1Data -) internal nonpayable; -``` - -Attempt to notify the operator `operator` about the `amount` tokens being authorized with. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP7_TOKENOPERATOR` as typeId, if `operator` is a contract that supports the LSP1 interface. -If `operator` is an EOA or a contract that does not support the LSP1 interface, nothing will happen and no notification will be sent. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------------------------------------------------ | -| `operator` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `lsp1Data` | `bytes` | the data to be sent to the `operator` address in the `universalReceiver` call. | - -
- -### \_notifyTokenSender - -```solidity -function _notifyTokenSender(address from, bytes lsp1Data) internal nonpayable; -``` - -Attempt to notify the token sender `from` about the `amount` of tokens being transferred. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP7_TOKENSSENDER` as typeId, if `from` is a contract that supports the LSP1 interface. -If `from` is an EOA or a contract that does not support the LSP1 interface, nothing will happen and no notification will be sent. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------------------------------------------------ | -| `from` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `lsp1Data` | `bytes` | the data to be sent to the `from` address in the `universalReceiver` call. | - -
- -### \_notifyTokenReceiver - -```solidity -function _notifyTokenReceiver( - address to, - bool force, - bytes lsp1Data -) internal nonpayable; -``` - -Attempt to notify the token receiver `to` about the `amount` tokens being received. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP7_TOKENSRECIPIENT` as typeId, if `to` is a contract that supports the LSP1 interface. -If `to` is is an EOA or a contract that does not support the LSP1 interface, the behaviour will depend on the `force` boolean flag. - -- if `force` is set to `true`, nothing will happen and no notification will be sent. - -- if `force` is set to `false, the transaction will revert. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | --------------------------------------------------------------------------------------------------- | -| `to` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `force` | `bool` | A boolean that describe if transfer to a `to` address that does not support LSP1 is allowed or not. | -| `lsp1Data` | `bytes` | The data to be sent to the `to` address in the `universalReceiver(...)` call. | - -
- -### \_supportsInterfaceInERC165Extension - -```solidity -function _supportsInterfaceInERC165Extension( - bytes4 interfaceId -) internal view returns (bool); -``` - -Returns whether the interfaceId being checked is supported in the extension of the -[`supportsInterface`](#supportsinterface) selector. -To be used by extendable contracts wishing to extend the ERC165 interfaceIds originally -supported by reading whether the interfaceId queried is supported in the `supportsInterface` -extension if the extension is set, if not it returns false. - -
- -### \_getExtensionAndForwardValue - -```solidity -function _getExtensionAndForwardValue( - bytes4 functionSelector -) internal view returns (address, bool); -``` - -Returns the extension address stored under the following data key: - -- [`_LSP17_EXTENSION_PREFIX`](#_lsp17_extension_prefix) + `` (Check [LSP2-ERC725YJSONSchema] for encoding the data key). - -- If no extension is stored, returns the address(0). - -- we do not check that payable bool as in lsp7 standard we will always forward the value to the extension - -
- -### \_fallbackLSP17Extendable - -:::info - -The LSP7 Token contract should not hold any native tokens. Any native tokens received by the contract -will be forwarded to the extension address mapped to the selector from `msg.sig`. - -::: - -```solidity -function _fallbackLSP17Extendable( - bytes callData -) internal nonpayable returns (bytes); -``` - -Forwards the call with the received value to an extension mapped to a function selector. -Calls [`_getExtensionAndForwardValue`](#_getextensionandforwardvalue) to get the address of the extension mapped to the function selector being -called on the account. If there is no extension, the address(0) will be returned. -Forwards the value if the extension is payable. -Reverts if there is no extension for the function being called. -If there is an extension for the function selector being called, it calls the extension with the -CALL opcode, passing the [`msg.data`](#msg.data) appended with the 20 bytes of the [`msg.sender`](#msg.sender) and -32 bytes of the [`msg.value`](#msg.value) - -
- -## Events - -### Approval - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#approval) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Event signature: `Approval(address,address,uint256)` -- Event topic hash: `0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925` - -::: - -```solidity -event Approval(address indexed owner, address indexed spender, uint256 value); -``` - -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` | - | -| `spender` **`indexed`** | `address` | - | -| `value` | `uint256` | - | - -
- -### DataChanged - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#datachanged) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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. | - -
- -### OperatorAuthorizationChanged - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#operatorauthorizationchanged) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Event signature: `OperatorAuthorizationChanged(address,address,uint256,bytes)` -- Event topic hash: `0xf772a43bfdf4729b196e3fb54a818b91a2ca6c49d10b2e16278752f9f515c25d` - -::: - -```solidity -event OperatorAuthorizationChanged(address indexed operator, address indexed tokenOwner, uint256 indexed amount, bytes operatorNotificationData); -``` - -Emitted when `tokenOwner` enables `operator` for `amount` tokens. - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ----------------------------------------------------------------------- | -| `operator` **`indexed`** | `address` | The address authorized as an operator | -| `tokenOwner` **`indexed`** | `address` | The token owner | -| `amount` **`indexed`** | `uint256` | The amount of tokens `operator` address has access to from `tokenOwner` | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### OperatorRevoked - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#operatorrevoked) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Event signature: `OperatorRevoked(address,address,bool,bytes)` -- Event topic hash: `0x0ebf5762d8855cbe012d2ca42fb33a81175e17c8a8751f8859931ba453bd4167` - -::: - -```solidity -event OperatorRevoked(address indexed operator, address indexed tokenOwner, bool indexed notified, bytes operatorNotificationData); -``` - -Emitted when `tokenOwner` disables `operator` for `amount` tokens and set its [`authorizedAmountFor(...)`](#`authorizedamountfor) to `0`. - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ------------------------------------------------------------- | -| `operator` **`indexed`** | `address` | The address revoked from operating | -| `tokenOwner` **`indexed`** | `address` | The token owner | -| `notified` **`indexed`** | `bool` | Bool indicating whether the operator has been notified or not | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### OwnershipTransferred - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#ownershiptransferred) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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` | - | - -
- -### Transfer - -:::note References - -- 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` - -::: - -```solidity -event Transfer(address indexed operator, address indexed from, address indexed to, uint256 amount, bool force, bytes data); -``` - -Emitted when the `from` transferred successfully `amount` of tokens to `to`. - -#### 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. | - -
- -### Transfer - -:::note References - -- 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` - -::: - -```solidity -event Transfer(address indexed from, address indexed to, uint256 value); -``` - -Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. - -#### Parameters - -| Name | Type | Description | -| -------------------- | :-------: | ----------- | -| `from` **`indexed`** | `address` | - | -| `to` **`indexed`** | `address` | - | -| `value` | `uint256` | - | - -
- -## Errors - -### ERC725Y_DataKeysValuesEmptyArray - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#erc725y_datakeysvaluesemptyarray) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#erc725y_datakeysvalueslengthmismatch) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#erc725y_msgvaluedisallowed) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `ERC725Y_MsgValueDisallowed()` -- Error hash: `0xf36ba737` - -::: - -```solidity -error ERC725Y_MsgValueDisallowed(); -``` - -Reverts when sending value to the [`setData`](#setdata) or [`setDataBatch`](#setdatabatch) function. - -
- -### InvalidExtensionAddress - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#invalidextensionaddress) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `InvalidExtensionAddress(bytes)` -- Error hash: `0x42bfe79f` - -::: - -```solidity -error InvalidExtensionAddress(bytes storedData); -``` - -reverts when the bytes retrieved from the LSP17 data key is not a valid address (not 20 bytes) - -#### Parameters - -| Name | Type | Description | -| ------------ | :-----: | ----------- | -| `storedData` | `bytes` | - | - -
- -### InvalidFunctionSelector - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#invalidfunctionselector) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `InvalidFunctionSelector(bytes)` -- Error hash: `0xe5099ee3` - -::: - -```solidity -error InvalidFunctionSelector(bytes data); -``` - -reverts when the contract is called with a function selector not valid (less than 4 bytes of data) - -#### Parameters - -| Name | Type | Description | -| ------ | :-----: | ----------- | -| `data` | `bytes` | - | - -
- -### LSP4TokenNameNotEditable - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp4tokennamenoteditable) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP4TokenNameNotEditable()` -- Error hash: `0x85c169bd` - -::: - -```solidity -error LSP4TokenNameNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenName` after the digital asset contract has been deployed / initialized. The `LSP4TokenName` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor/initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP4TokenSymbolNotEditable - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp4tokensymbolnoteditable) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP4TokenSymbolNotEditable()` -- Error hash: `0x76755b38` - -::: - -```solidity -error LSP4TokenSymbolNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenSymbol` after the digital asset contract has been deployed / initialized. The `LSP4TokenSymbol` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor/initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP4TokenTypeNotEditable - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp4tokentypenoteditable) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP4TokenTypeNotEditable()` -- Error hash: `0x4ef6d7fb` - -::: - -```solidity -error LSP4TokenTypeNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenType` after the digital asset contract has been deployed / initialized. The `LSP4TokenType` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor / initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP7AmountExceedsAuthorizedAmount - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7amountexceedsauthorizedamount) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7AmountExceedsAuthorizedAmount(address,uint256,address,uint256)` -- Error hash: `0xf3a6b691` - -::: - -```solidity -error LSP7AmountExceedsAuthorizedAmount( - address tokenOwner, - uint256 authorizedAmount, - address operator, - uint256 amount -); -``` - -reverts when `operator` of `tokenOwner` send an `amount` of tokens larger than the `authorizedAmount`. - -#### Parameters - -| Name | Type | Description | -| ------------------ | :-------: | ----------- | -| `tokenOwner` | `address` | - | -| `authorizedAmount` | `uint256` | - | -| `operator` | `address` | - | -| `amount` | `uint256` | - | - -
- -### LSP7AmountExceedsBalance - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7amountexceedsbalance) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7AmountExceedsBalance(uint256,address,uint256)` -- Error hash: `0x08d47949` - -::: - -```solidity -error LSP7AmountExceedsBalance( - uint256 balance, - address tokenOwner, - uint256 amount -); -``` - -reverts when sending an `amount` of tokens larger than the current `balance` of the `tokenOwner`. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ----------- | -| `balance` | `uint256` | - | -| `tokenOwner` | `address` | - | -| `amount` | `uint256` | - | - -
- -### LSP7BatchCallFailed - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7batchcallfailed) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7BatchCallFailed(uint256)` -- Error hash: `0xb774c284` - -::: - -```solidity -error LSP7BatchCallFailed(uint256 callIndex); -``` - -_Batch call failed._ - -Reverts when a batch call failed. - -#### Parameters - -| Name | Type | Description | -| ----------- | :-------: | ----------- | -| `callIndex` | `uint256` | - | - -
- -### LSP7CannotSendToSelf - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7cannotsendtoself) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7CannotSendToSelf()` -- Error hash: `0xb9afb000` - -::: - -```solidity -error LSP7CannotSendToSelf(); -``` - -reverts when specifying the same address for `from` or `to` in a token transfer. - -
- -### LSP7CannotSendWithAddressZero - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7cannotsendwithaddresszero) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7CannotSendWithAddressZero()` -- Error hash: `0xd2d5ec30` - -::: - -```solidity -error LSP7CannotSendWithAddressZero(); -``` - -reverts when trying to: - -- mint tokens to the zero address. - -- burn tokens from the zero address. - -- transfer tokens from or to the zero address. - -
- -### LSP7CannotUseAddressZeroAsOperator - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7cannotuseaddresszeroasoperator) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7CannotUseAddressZeroAsOperator()` -- Error hash: `0x6355e766` - -::: - -```solidity -error LSP7CannotUseAddressZeroAsOperator(); -``` - -reverts when trying to set the zero address as an operator. - -
- -### LSP7DecreasedAllowanceBelowZero - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7decreasedallowancebelowzero) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7DecreasedAllowanceBelowZero()` -- Error hash: `0x0ef76c35` - -::: - -```solidity -error LSP7DecreasedAllowanceBelowZero(); -``` - -Reverts when trying to decrease an operator's allowance to more than its current allowance. - -
- -### LSP7InvalidTransferBatch - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7invalidtransferbatch) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7InvalidTransferBatch()` -- Error hash: `0x263eee8d` - -::: - -```solidity -error LSP7InvalidTransferBatch(); -``` - -reverts when the array parameters used in [`transferBatch`](#transferbatch) have different lengths. - -
- -### LSP7NotifyTokenReceiverContractMissingLSP1Interface - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7notifytokenreceivercontractmissinglsp1interface) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7NotifyTokenReceiverContractMissingLSP1Interface(address)` -- Error hash: `0xa608fbb6` - -::: - -```solidity -error LSP7NotifyTokenReceiverContractMissingLSP1Interface( - address tokenReceiver -); -``` - -reverts if the `tokenReceiver` does not implement LSP1 when minting or transferring tokens with `bool force` set as `false`. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ----------- | -| `tokenReceiver` | `address` | - | - -
- -### LSP7NotifyTokenReceiverIsEOA - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7notifytokenreceiveriseoa) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7NotifyTokenReceiverIsEOA(address)` -- Error hash: `0x26c247f4` - -::: - -```solidity -error LSP7NotifyTokenReceiverIsEOA(address tokenReceiver); -``` - -reverts if the `tokenReceiver` is an EOA when minting or transferring tokens with `bool force` set as `false`. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ----------- | -| `tokenReceiver` | `address` | - | - -
- -### LSP7TokenContractCannotHoldValue - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7tokencontractcannotholdvalue) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7TokenContractCannotHoldValue()` -- Error hash: `0x388f5adc` - -::: - -```solidity -error LSP7TokenContractCannotHoldValue(); -``` - -_LSP7 contract cannot receive native tokens._ - -Error occurs when sending native tokens to the LSP7 contract without sending any data. E.g. Sending value without passing a bytes4 function selector to call a LSP17 Extension. - -
- -### LSP7TokenOwnerCannotBeOperator - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7tokenownercannotbeoperator) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `LSP7TokenOwnerCannotBeOperator()` -- Error hash: `0xdab75047` - -::: - -```solidity -error LSP7TokenOwnerCannotBeOperator(); -``` - -reverts when trying to authorize or revoke the token's owner as an operator. - -
- -### NoExtensionFoundForFunctionSelector - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#noextensionfoundforfunctionselector) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `NoExtensionFoundForFunctionSelector(bytes4)` -- Error hash: `0xbb370b2b` - -::: - -```solidity -error NoExtensionFoundForFunctionSelector(bytes4 functionSelector); -``` - -reverts when there is no extension for the function selector being called with - -#### Parameters - -| Name | Type | Description | -| ------------------ | :------: | ----------- | -| `functionSelector` | `bytes4` | - | - -
- -### OperatorAllowanceCannotBeIncreasedFromZero - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#operatorallowancecannotbeincreasedfromzero) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol) -- Error signature: `OperatorAllowanceCannotBeIncreasedFromZero(address)` -- Error hash: `0xcba6e977` - -::: - -```solidity -error OperatorAllowanceCannotBeIncreasedFromZero(address operator); -``` - -Reverts when token owner call [`increaseAllowance`](#increaseallowance) for an operator that does not have any allowance - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `operator` | `address` | - | - -
- -### OwnableCallerNotTheOwner - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#ownablecallernottheowner) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#ownablecannotsetzeroaddressasowner) -- Solidity implementation: [`LSP7CompatibleERC20.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.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/presets/LSP7CompatibleERC20Mintable.md b/docs/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.md deleted file mode 100644 index a1c1124a3..000000000 --- a/docs/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.md +++ /dev/null @@ -1,2031 +0,0 @@ - - - -# LSP7CompatibleERC20Mintable - -:::info Standard Specifications - -[`LSP-7-DigitalAsset`](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md) - -::: -:::info Solidity implementation - -[`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) - -::: - -> LSP7CompatibleERC20 deployable preset contract with a public [`mint`](#mint) function callable only by the contract [`owner`](#owner). - -## 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. - -### constructor - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#constructor) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) - -::: - -```solidity -constructor( - string name_, - string symbol_, - address newOwner_, - uint256 lsp4TokenType_ -); -``` - -_Deploying a `LSP7CompatibleERC20Mintable` token contract with: token name = `name_`, token symbol = `symbol_`, and address `newOwner_` as the token contract owner._ - -#### Parameters - -| Name | Type | Description | -| ---------------- | :-------: | ---------------------------------------------------------------------------------------------------- | -| `name_` | `string` | The name of the token. | -| `symbol_` | `string` | The symbol of the token. | -| `newOwner_` | `address` | The owner of the token contract. | -| `lsp4TokenType_` | `uint256` | The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection). | - -
- -### fallback - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#fallback) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) - -::: - -```solidity -fallback() external payable; -``` - -
- -### receive - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#receive) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) - -::: - -```solidity -receive() external payable; -``` - -
- -### allowance - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#allowance) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `allowance(address,address)` -- Function selector: `0xdd62ed3e` - -::: - -```solidity -function allowance( - address tokenOwner, - address operator -) 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` | The address of the token owner | -| `operator` | `address` | The address approved by the `tokenOwner` | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------------------------------- | -| `0` | `uint256` | The amount `operator` is approved by `tokenOwner` | - -
- -### approve - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#approve) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `approve(address,uint256)` -- Function selector: `0x095ea7b3` - -::: - -```solidity -function approve( - address operator, - uint256 amount -) external nonpayable returns (bool); -``` - -Approval function from th ERC20 standard interface. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ----------------------------------- | -| `operator` | `address` | The address to approve for `amount` | -| `amount` | `uint256` | The amount to approve. | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | ------------------------------ | -| `0` | `bool` | `true` on successful approval. | - -
- -### authorizeOperator - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#authorizeoperator) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `authorizeOperator(address,uint256,bytes)` -- Function selector: `0xb49506fd` - -::: - -:::danger - -To avoid front-running and Allowance Double-Spend Exploit when increasing or decreasing the authorized amount of an operator, it is advised to use the [`increaseAllowance`](#increaseallowance) and [`decreaseAllowance`](#decreaseallowance) functions. For more information, see: https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/ - -::: - -```solidity -function authorizeOperator( - address operator, - uint256 amount, - bytes operatorNotificationData -) external nonpayable; -``` - -Sets an `amount` of tokens that an `operator` has access from the caller's balance (allowance). See [`authorizedAmountFor`](#authorizedamountfor). Notify the operator based on the LSP1-UniversalReceiver standard - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ------------------------------------------------------ | -| `operator` | `address` | The address to authorize as an operator. | -| `amount` | `uint256` | The allowance amount of tokens operator has access to. | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### authorizedAmountFor - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#authorizedamountfor) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `authorizedAmountFor(address,address)` -- Function selector: `0x65aeaa95` - -::: - -```solidity -function authorizedAmountFor( - address operator, - address tokenOwner -) external view returns (uint256); -``` - -Get the amount of tokens `operator` address has access to from `tokenOwner`. Operators can send and burn tokens on behalf of their owners. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ---------------------------------------------------------- | -| `operator` | `address` | The operator's address to query the authorized amount for. | -| `tokenOwner` | `address` | The token owner that `operator` has allowance on. | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | --------------------------------------------------------------------------------------- | -| `0` | `uint256` | The amount of tokens the `operator`'s address has access on the `tokenOwner`'s balance. | - -
- -### balanceOf - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#balanceof) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `balanceOf(address)` -- Function selector: `0x70a08231` - -::: - -```solidity -function balanceOf(address tokenOwner) external view returns (uint256); -``` - -Get the number of tokens owned by `tokenOwner`. If the token is divisible (the [`decimals`](#decimals) function returns `18`), the amount returned should be divided by 1e18 to get a better picture of the actual balance of the `tokenOwner`. _Example:_ `balanceOf(someAddress) -> 42_000_000_000_000_000_000 / 1e18 = 42 tokens` - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | --------------------------------------------------------- | -| `tokenOwner` | `address` | The address of the token holder to query the balance for. | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------------------------- | -| `0` | `uint256` | The amount of tokens owned by `tokenOwner`. | - -
- -### batchCalls - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#batchcalls) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `batchCalls(bytes[])` -- Function selector: `0x6963d438` - -::: - -:::info - -It's not possible to send value along the functions call due to the use of `delegatecall`. - -::: - -```solidity -function batchCalls(bytes[] data) external nonpayable returns (bytes[] results); -``` - -_Executing the following batch of abi-encoded function calls on the contract: `data`._ - -Allows a caller to batch different function calls in one call. Perform a `delegatecall` on self, to call different functions with preserving the context. - -#### Parameters - -| Name | Type | Description | -| ------ | :-------: | -------------------------------------------------------------------- | -| `data` | `bytes[]` | An array of ABI encoded function calls to be called on the contract. | - -#### Returns - -| Name | Type | Description | -| --------- | :-------: | ---------------------------------------------------------------- | -| `results` | `bytes[]` | An array of abi-encoded data returned by the functions executed. | - -
- -### decimals - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#decimals) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `decimals()` -- Function selector: `0x313ce567` - -::: - -```solidity -function decimals() external view returns (uint8); -``` - -Returns the number of decimals used to get its user representation. If the asset contract has been set to be non-divisible via the `isNonDivisible_` parameter in the `constructor`, the decimals returned wiil be `0`. Otherwise `18` is the common value. - -#### Returns - -| Name | Type | Description | -| ---- | :-----: | ----------------------------------------------------------------------- | -| `0` | `uint8` | the number of decimals. If `0` is returned, the asset is non-divisible. | - -
- -### decreaseAllowance - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#decreaseallowance) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `decreaseAllowance(address,uint256,bytes)` -- Function selector: `0x7b204c4e` - -::: - -```solidity -function decreaseAllowance( - address operator, - uint256 subtractedAmount, - bytes operatorNotificationData -) external nonpayable; -``` - -_Decrease the allowance of `operator` by -`subtractedAmount`_ - -Atomically decreases the allowance granted to `operator` by the caller. This is an alternative approach to [`authorizeOperator`](#authorizeoperator) that can be used as a mitigation for the double spending allowance problem. Notify the operator based on the LSP1-UniversalReceiver standard - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ------------------------------------------------------ | -| `operator` | `address` | The operator to decrease allowance for `msg.sender` | -| `subtractedAmount` | `uint256` | The amount to decrease by in the operator's allowance. | -| `operatorNotificationData` | `bytes` | - | - -
- -### getData - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#getdata) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#getdatabatch) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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 | - -
- -### getOperatorsOf - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#getoperatorsof) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `getOperatorsOf(address)` -- Function selector: `0xd72fc29a` - -::: - -```solidity -function getOperatorsOf(address tokenOwner) external view returns (address[]); -``` - -Returns all `operator` addresses that are allowed to transfer or burn on behalf of `tokenOwner`. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ----------------------------------------- | -| `tokenOwner` | `address` | The token owner to get the operators for. | - -#### Returns - -| Name | Type | Description | -| ---- | :---------: | ----------------------------------------------------------------------------------- | -| `0` | `address[]` | An array of operators allowed to transfer or burn tokens on behalf of `tokenOwner`. | - -
- -### increaseAllowance - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#increaseallowance) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `increaseAllowance(address,uint256,bytes)` -- Function selector: `0x2bc1da82` - -::: - -```solidity -function increaseAllowance( - address operator, - uint256 addedAmount, - bytes operatorNotificationData -) external nonpayable; -``` - -_Increase the allowance of `operator` by +`addedAmount`_ - -Atomically increases the allowance granted to `operator` by the caller. This is an alternative approach to [`authorizeOperator`](#authorizeoperator) that can be used as a mitigation for the double spending allowance problem. Notify the operator based on the LSP1-UniversalReceiver standard - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ----------------------------------------------------------------------- | -| `operator` | `address` | The operator to increase the allowance for `msg.sender` | -| `addedAmount` | `uint256` | The additional amount to add on top of the current operator's allowance | -| `operatorNotificationData` | `bytes` | - | - -
- -### mint - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#mint) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `mint(address,uint256,bool,bytes)` -- Function selector: `0x7580d920` - -::: - -```solidity -function mint( - address to, - uint256 amount, - bool force, - bytes data -) external nonpayable; -``` - -Public [`_mint`](#_mint) function only callable by the [`owner`](#owner). - -#### Parameters - -| Name | Type | Description | -| -------- | :-------: | ----------- | -| `to` | `address` | - | -| `amount` | `uint256` | - | -| `force` | `bool` | - | -| `data` | `bytes` | - | - -
- -### name - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#name) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `name()` -- Function selector: `0x06fdde03` - -::: - -```solidity -function name() external view returns (string); -``` - -Returns the name of the token. For compatibility with clients & tools that expect ERC20. - -#### Returns - -| Name | Type | Description | -| ---- | :------: | --------------------- | -| `0` | `string` | The name of the token | - -
- -### owner - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#owner) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#renounceownership) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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. - -
- -### revokeOperator - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#revokeoperator) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `revokeOperator(address,bool,bytes)` -- Function selector: `0x4521748e` - -::: - -```solidity -function revokeOperator( - address operator, - bool notify, - bytes operatorNotificationData -) external nonpayable; -``` - -Removes the `operator` address as an operator of callers tokens, disallowing it to send any amount of tokens on behalf of the token owner (the caller of the function `msg.sender`). See also [`authorizedAmountFor`](#authorizedamountfor). - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | --------------------------------------------------------- | -| `operator` | `address` | The address to revoke as an operator. | -| `notify` | `bool` | Boolean indicating whether to notify the operator or not. | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### setData - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#setdata) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#setdatabatch) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#supportsinterface) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `supportsInterface(bytes4)` -- Function selector: `0x01ffc9a7` - -::: - -```solidity -function supportsInterface(bytes4 interfaceId) external view returns (bool); -``` - -Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas. - -#### Parameters - -| Name | Type | Description | -| ------------- | :------: | ----------- | -| `interfaceId` | `bytes4` | - | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | - -
- -### symbol - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#symbol) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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. For compatibility with clients & tools that expect ERC20. - -#### Returns - -| Name | Type | Description | -| ---- | :------: | ----------------------- | -| `0` | `string` | The symbol of the token | - -
- -### totalSupply - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#totalsupply) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `totalSupply()` -- Function selector: `0x18160ddd` - -::: - -```solidity -function totalSupply() external view returns (uint256); -``` - -Returns the number of existing tokens that have been minted in this contract. - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------------ | -| `0` | `uint256` | The number of existing tokens. | - -
- -### transfer - -:::note References - -- 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) -- Function signature: `transfer(address,address,uint256,bool,bytes)` -- Function selector: `0x760d9bba` - -::: - -```solidity -function transfer( - address from, - address to, - uint256 amount, - bool force, - bytes data -) external nonpayable; -``` - -Transfers an `amount` of tokens from the `from` address to the `to` address and notify both sender and recipients via the LSP1 [`universalReceiver(...)`](#`universalreceiver) function. If the tokens are transferred by an operator on behalf of a token holder, the allowance for the operator will be decreased by `amount` once the token transfer has been completed (See [`authorizedAmountFor`](#authorizedamountfor)). - -#### Parameters - -| Name | Type | Description | -| -------- | :-------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `from` | `address` | The sender address. | -| `to` | `address` | The recipient address. | -| `amount` | `uint256` | The amount of tokens to transfer. | -| `force` | `bool` | When set to `true`, the `to` address CAN be any address. When set to `false`, the `to` address MUST be a contract that supports the LSP1 UniversalReceiver standard. | -| `data` | `bytes` | Any additional data the caller wants included in the emitted event, and sent in the hooks of the `from` and `to` addresses. | - -
- -### transfer - -:::note References - -- 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) -- Function signature: `transfer(address,uint256)` -- Function selector: `0xa9059cbb` - -::: - -:::info - -This function uses the `force` parameter as `true` so that EOA and any contract can receive tokens. - -::: - -```solidity -function transfer( - address to, - uint256 amount -) external nonpayable returns (bool); -``` - -Transfer function from the ERC20 standard interface. - -#### Parameters - -| Name | Type | Description | -| -------- | :-------: | --------------------------------- | -| `to` | `address` | The address receiving tokens. | -| `amount` | `uint256` | The amount of tokens to transfer. | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | ------------------------------ | -| `0` | `bool` | `true` on successful transfer. | - -
- -### transferBatch - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#transferbatch) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `transferBatch(address[],address[],uint256[],bool[],bytes[])` -- Function selector: `0x2d7667c9` - -::: - -```solidity -function transferBatch( - address[] from, - address[] to, - uint256[] amount, - bool[] force, - bytes[] data -) external nonpayable; -``` - -Same as [`transfer(...)`](#`transfer) but transfer multiple tokens based on the arrays of `from`, `to`, `amount`. - -#### Parameters - -| Name | Type | Description | -| -------- | :---------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `from` | `address[]` | An array of sending addresses. | -| `to` | `address[]` | An array of receiving addresses. | -| `amount` | `uint256[]` | An array of amount of tokens to transfer for each `from -> to` transfer. | -| `force` | `bool[]` | For each transfer, when set to `true`, the `to` address CAN be any address. When set to `false`, the `to` address MUST be a contract that supports the LSP1 UniversalReceiver standard. | -| `data` | `bytes[]` | An array of additional data the caller wants included in the emitted event, and sent in the hooks to `from` and `to` addresses. | - -
- -### transferFrom - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#transferfrom) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Function signature: `transferFrom(address,address,uint256)` -- Function selector: `0x23b872dd` - -::: - -:::info - -This function uses the `force` parameter as `true` so that EOA and any contract can receive tokens. - -::: - -```solidity -function transferFrom( - address from, - address to, - uint256 amount -) external nonpayable returns (bool); -``` - -Transfer functions for operators from the ERC20 standard interface. - -#### Parameters - -| 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` | `true` on successful transfer. | - -
- -### transferOwnership - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#transferownership) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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; -``` - -The ERC725Y data keys `LSP4TokenName` and `LSP4TokenSymbol` cannot be changed -via this function once the digital asset contract has been deployed. - -
- -### \_updateOperator - -```solidity -function _updateOperator( - address tokenOwner, - address operator, - uint256 amount, - bool notified, - bytes operatorNotificationData -) internal nonpayable; -``` - -
- -### \_mint - -```solidity -function _mint( - address to, - uint256 amount, - bool force, - bytes data -) internal nonpayable; -``` - -
- -### \_burn - -```solidity -function _burn(address from, uint256 amount, bytes data) internal nonpayable; -``` - -
- -### \_spendAllowance - -```solidity -function _spendAllowance( - address operator, - address tokenOwner, - uint256 amountToSpend -) internal nonpayable; -``` - -Spend `amountToSpend` from the `operator`'s authorized on behalf of the `tokenOwner`. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ------------------------------------------------------------------- | -| `operator` | `address` | The address of the operator to decrease the allowance of. | -| `tokenOwner` | `address` | The address that granted an allowance on its balance to `operator`. | -| `amountToSpend` | `uint256` | The amount of tokens to substract in allowance of `operator`. | - -
- -### \_transfer - -```solidity -function _transfer( - address from, - address to, - uint256 amount, - bool force, - bytes data -) internal nonpayable; -``` - -
- -### \_beforeTokenTransfer - -```solidity -function _beforeTokenTransfer( - address from, - address to, - uint256 amount, - bytes data -) internal nonpayable; -``` - -Hook that is called before any token transfer, including minting and burning. -Allows to run custom logic before updating balances and notifiying sender/recipient by overriding this function. - -#### Parameters - -| Name | Type | Description | -| -------- | :-------: | ------------------------------------ | -| `from` | `address` | The sender address | -| `to` | `address` | The recipient address | -| `amount` | `uint256` | The amount of token to transfer | -| `data` | `bytes` | The data sent alongside the transfer | - -
- -### \_afterTokenTransfer - -```solidity -function _afterTokenTransfer( - address from, - address to, - uint256 amount, - bytes data -) internal nonpayable; -``` - -Hook that is called after any token transfer, including minting and burning. -Allows to run custom logic after updating balances, but **before notifiying sender/recipient** by overriding this function. - -#### Parameters - -| Name | Type | Description | -| -------- | :-------: | ------------------------------------ | -| `from` | `address` | The sender address | -| `to` | `address` | The recipient address | -| `amount` | `uint256` | The amount of token to transfer | -| `data` | `bytes` | The data sent alongside the transfer | - -
- -### \_notifyTokenOperator - -```solidity -function _notifyTokenOperator( - address operator, - bytes lsp1Data -) internal nonpayable; -``` - -Attempt to notify the operator `operator` about the `amount` tokens being authorized with. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP7_TOKENOPERATOR` as typeId, if `operator` is a contract that supports the LSP1 interface. -If `operator` is an EOA or a contract that does not support the LSP1 interface, nothing will happen and no notification will be sent. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------------------------------------------------ | -| `operator` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `lsp1Data` | `bytes` | the data to be sent to the `operator` address in the `universalReceiver` call. | - -
- -### \_notifyTokenSender - -```solidity -function _notifyTokenSender(address from, bytes lsp1Data) internal nonpayable; -``` - -Attempt to notify the token sender `from` about the `amount` of tokens being transferred. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP7_TOKENSSENDER` as typeId, if `from` is a contract that supports the LSP1 interface. -If `from` is an EOA or a contract that does not support the LSP1 interface, nothing will happen and no notification will be sent. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------------------------------------------------ | -| `from` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `lsp1Data` | `bytes` | the data to be sent to the `from` address in the `universalReceiver` call. | - -
- -### \_notifyTokenReceiver - -```solidity -function _notifyTokenReceiver( - address to, - bool force, - bytes lsp1Data -) internal nonpayable; -``` - -Attempt to notify the token receiver `to` about the `amount` tokens being received. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP7_TOKENSRECIPIENT` as typeId, if `to` is a contract that supports the LSP1 interface. -If `to` is is an EOA or a contract that does not support the LSP1 interface, the behaviour will depend on the `force` boolean flag. - -- if `force` is set to `true`, nothing will happen and no notification will be sent. - -- if `force` is set to `false, the transaction will revert. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | --------------------------------------------------------------------------------------------------- | -| `to` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `force` | `bool` | A boolean that describe if transfer to a `to` address that does not support LSP1 is allowed or not. | -| `lsp1Data` | `bytes` | The data to be sent to the `to` address in the `universalReceiver(...)` call. | - -
- -### \_supportsInterfaceInERC165Extension - -```solidity -function _supportsInterfaceInERC165Extension( - bytes4 interfaceId -) internal view returns (bool); -``` - -Returns whether the interfaceId being checked is supported in the extension of the -[`supportsInterface`](#supportsinterface) selector. -To be used by extendable contracts wishing to extend the ERC165 interfaceIds originally -supported by reading whether the interfaceId queried is supported in the `supportsInterface` -extension if the extension is set, if not it returns false. - -
- -### \_getExtensionAndForwardValue - -```solidity -function _getExtensionAndForwardValue( - bytes4 functionSelector -) internal view returns (address, bool); -``` - -Returns the extension address stored under the following data key: - -- [`_LSP17_EXTENSION_PREFIX`](#_lsp17_extension_prefix) + `` (Check [LSP2-ERC725YJSONSchema] for encoding the data key). - -- If no extension is stored, returns the address(0). - -- we do not check that payable bool as in lsp7 standard we will always forward the value to the extension - -
- -### \_fallbackLSP17Extendable - -:::info - -The LSP7 Token contract should not hold any native tokens. Any native tokens received by the contract -will be forwarded to the extension address mapped to the selector from `msg.sig`. - -::: - -```solidity -function _fallbackLSP17Extendable( - bytes callData -) internal nonpayable returns (bytes); -``` - -Forwards the call with the received value to an extension mapped to a function selector. -Calls [`_getExtensionAndForwardValue`](#_getextensionandforwardvalue) to get the address of the extension mapped to the function selector being -called on the account. If there is no extension, the address(0) will be returned. -Forwards the value if the extension is payable. -Reverts if there is no extension for the function being called. -If there is an extension for the function selector being called, it calls the extension with the -CALL opcode, passing the [`msg.data`](#msg.data) appended with the 20 bytes of the [`msg.sender`](#msg.sender) and -32 bytes of the [`msg.value`](#msg.value) - -
- -## Events - -### Approval - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#approval) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Event signature: `Approval(address,address,uint256)` -- Event topic hash: `0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925` - -::: - -```solidity -event Approval(address indexed owner, address indexed spender, uint256 value); -``` - -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` | - | -| `spender` **`indexed`** | `address` | - | -| `value` | `uint256` | - | - -
- -### DataChanged - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#datachanged) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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. | - -
- -### OperatorAuthorizationChanged - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#operatorauthorizationchanged) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Event signature: `OperatorAuthorizationChanged(address,address,uint256,bytes)` -- Event topic hash: `0xf772a43bfdf4729b196e3fb54a818b91a2ca6c49d10b2e16278752f9f515c25d` - -::: - -```solidity -event OperatorAuthorizationChanged(address indexed operator, address indexed tokenOwner, uint256 indexed amount, bytes operatorNotificationData); -``` - -Emitted when `tokenOwner` enables `operator` for `amount` tokens. - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ----------------------------------------------------------------------- | -| `operator` **`indexed`** | `address` | The address authorized as an operator | -| `tokenOwner` **`indexed`** | `address` | The token owner | -| `amount` **`indexed`** | `uint256` | The amount of tokens `operator` address has access to from `tokenOwner` | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### OperatorRevoked - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#operatorrevoked) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Event signature: `OperatorRevoked(address,address,bool,bytes)` -- Event topic hash: `0x0ebf5762d8855cbe012d2ca42fb33a81175e17c8a8751f8859931ba453bd4167` - -::: - -```solidity -event OperatorRevoked(address indexed operator, address indexed tokenOwner, bool indexed notified, bytes operatorNotificationData); -``` - -Emitted when `tokenOwner` disables `operator` for `amount` tokens and set its [`authorizedAmountFor(...)`](#`authorizedamountfor) to `0`. - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ------------------------------------------------------------- | -| `operator` **`indexed`** | `address` | The address revoked from operating | -| `tokenOwner` **`indexed`** | `address` | The token owner | -| `notified` **`indexed`** | `bool` | Bool indicating whether the operator has been notified or not | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### OwnershipTransferred - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#ownershiptransferred) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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` | - | - -
- -### Transfer - -:::note References - -- 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` - -::: - -```solidity -event Transfer(address indexed operator, address indexed from, address indexed to, uint256 amount, bool force, bytes data); -``` - -Emitted when the `from` transferred successfully `amount` of tokens to `to`. - -#### 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. | - -
- -### Transfer - -:::note References - -- 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` - -::: - -```solidity -event Transfer(address indexed from, address indexed to, uint256 value); -``` - -Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. - -#### Parameters - -| Name | Type | Description | -| -------------------- | :-------: | ----------- | -| `from` **`indexed`** | `address` | - | -| `to` **`indexed`** | `address` | - | -| `value` | `uint256` | - | - -
- -## Errors - -### ERC725Y_DataKeysValuesEmptyArray - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#erc725y_datakeysvaluesemptyarray) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#erc725y_datakeysvalueslengthmismatch) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#erc725y_msgvaluedisallowed) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `ERC725Y_MsgValueDisallowed()` -- Error hash: `0xf36ba737` - -::: - -```solidity -error ERC725Y_MsgValueDisallowed(); -``` - -Reverts when sending value to the [`setData`](#setdata) or [`setDataBatch`](#setdatabatch) function. - -
- -### InvalidExtensionAddress - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#invalidextensionaddress) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `InvalidExtensionAddress(bytes)` -- Error hash: `0x42bfe79f` - -::: - -```solidity -error InvalidExtensionAddress(bytes storedData); -``` - -reverts when the bytes retrieved from the LSP17 data key is not a valid address (not 20 bytes) - -#### Parameters - -| Name | Type | Description | -| ------------ | :-----: | ----------- | -| `storedData` | `bytes` | - | - -
- -### InvalidFunctionSelector - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#invalidfunctionselector) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `InvalidFunctionSelector(bytes)` -- Error hash: `0xe5099ee3` - -::: - -```solidity -error InvalidFunctionSelector(bytes data); -``` - -reverts when the contract is called with a function selector not valid (less than 4 bytes of data) - -#### Parameters - -| Name | Type | Description | -| ------ | :-----: | ----------- | -| `data` | `bytes` | - | - -
- -### LSP4TokenNameNotEditable - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp4tokennamenoteditable) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP4TokenNameNotEditable()` -- Error hash: `0x85c169bd` - -::: - -```solidity -error LSP4TokenNameNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenName` after the digital asset contract has been deployed / initialized. The `LSP4TokenName` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor/initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP4TokenSymbolNotEditable - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp4tokensymbolnoteditable) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP4TokenSymbolNotEditable()` -- Error hash: `0x76755b38` - -::: - -```solidity -error LSP4TokenSymbolNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenSymbol` after the digital asset contract has been deployed / initialized. The `LSP4TokenSymbol` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor/initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP4TokenTypeNotEditable - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp4tokentypenoteditable) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP4TokenTypeNotEditable()` -- Error hash: `0x4ef6d7fb` - -::: - -```solidity -error LSP4TokenTypeNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenType` after the digital asset contract has been deployed / initialized. The `LSP4TokenType` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor / initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP7AmountExceedsAuthorizedAmount - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7amountexceedsauthorizedamount) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7AmountExceedsAuthorizedAmount(address,uint256,address,uint256)` -- Error hash: `0xf3a6b691` - -::: - -```solidity -error LSP7AmountExceedsAuthorizedAmount( - address tokenOwner, - uint256 authorizedAmount, - address operator, - uint256 amount -); -``` - -reverts when `operator` of `tokenOwner` send an `amount` of tokens larger than the `authorizedAmount`. - -#### Parameters - -| Name | Type | Description | -| ------------------ | :-------: | ----------- | -| `tokenOwner` | `address` | - | -| `authorizedAmount` | `uint256` | - | -| `operator` | `address` | - | -| `amount` | `uint256` | - | - -
- -### LSP7AmountExceedsBalance - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7amountexceedsbalance) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7AmountExceedsBalance(uint256,address,uint256)` -- Error hash: `0x08d47949` - -::: - -```solidity -error LSP7AmountExceedsBalance( - uint256 balance, - address tokenOwner, - uint256 amount -); -``` - -reverts when sending an `amount` of tokens larger than the current `balance` of the `tokenOwner`. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ----------- | -| `balance` | `uint256` | - | -| `tokenOwner` | `address` | - | -| `amount` | `uint256` | - | - -
- -### LSP7BatchCallFailed - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7batchcallfailed) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7BatchCallFailed(uint256)` -- Error hash: `0xb774c284` - -::: - -```solidity -error LSP7BatchCallFailed(uint256 callIndex); -``` - -_Batch call failed._ - -Reverts when a batch call failed. - -#### Parameters - -| Name | Type | Description | -| ----------- | :-------: | ----------- | -| `callIndex` | `uint256` | - | - -
- -### LSP7CannotSendToSelf - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7cannotsendtoself) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7CannotSendToSelf()` -- Error hash: `0xb9afb000` - -::: - -```solidity -error LSP7CannotSendToSelf(); -``` - -reverts when specifying the same address for `from` or `to` in a token transfer. - -
- -### LSP7CannotSendWithAddressZero - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7cannotsendwithaddresszero) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7CannotSendWithAddressZero()` -- Error hash: `0xd2d5ec30` - -::: - -```solidity -error LSP7CannotSendWithAddressZero(); -``` - -reverts when trying to: - -- mint tokens to the zero address. - -- burn tokens from the zero address. - -- transfer tokens from or to the zero address. - -
- -### LSP7CannotUseAddressZeroAsOperator - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7cannotuseaddresszeroasoperator) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7CannotUseAddressZeroAsOperator()` -- Error hash: `0x6355e766` - -::: - -```solidity -error LSP7CannotUseAddressZeroAsOperator(); -``` - -reverts when trying to set the zero address as an operator. - -
- -### LSP7DecreasedAllowanceBelowZero - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7decreasedallowancebelowzero) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7DecreasedAllowanceBelowZero()` -- Error hash: `0x0ef76c35` - -::: - -```solidity -error LSP7DecreasedAllowanceBelowZero(); -``` - -Reverts when trying to decrease an operator's allowance to more than its current allowance. - -
- -### LSP7InvalidTransferBatch - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7invalidtransferbatch) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7InvalidTransferBatch()` -- Error hash: `0x263eee8d` - -::: - -```solidity -error LSP7InvalidTransferBatch(); -``` - -reverts when the array parameters used in [`transferBatch`](#transferbatch) have different lengths. - -
- -### LSP7NotifyTokenReceiverContractMissingLSP1Interface - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7notifytokenreceivercontractmissinglsp1interface) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7NotifyTokenReceiverContractMissingLSP1Interface(address)` -- Error hash: `0xa608fbb6` - -::: - -```solidity -error LSP7NotifyTokenReceiverContractMissingLSP1Interface( - address tokenReceiver -); -``` - -reverts if the `tokenReceiver` does not implement LSP1 when minting or transferring tokens with `bool force` set as `false`. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ----------- | -| `tokenReceiver` | `address` | - | - -
- -### LSP7NotifyTokenReceiverIsEOA - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7notifytokenreceiveriseoa) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7NotifyTokenReceiverIsEOA(address)` -- Error hash: `0x26c247f4` - -::: - -```solidity -error LSP7NotifyTokenReceiverIsEOA(address tokenReceiver); -``` - -reverts if the `tokenReceiver` is an EOA when minting or transferring tokens with `bool force` set as `false`. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ----------- | -| `tokenReceiver` | `address` | - | - -
- -### LSP7TokenContractCannotHoldValue - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7tokencontractcannotholdvalue) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7TokenContractCannotHoldValue()` -- Error hash: `0x388f5adc` - -::: - -```solidity -error LSP7TokenContractCannotHoldValue(); -``` - -_LSP7 contract cannot receive native tokens._ - -Error occurs when sending native tokens to the LSP7 contract without sending any data. E.g. Sending value without passing a bytes4 function selector to call a LSP17 Extension. - -
- -### LSP7TokenOwnerCannotBeOperator - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#lsp7tokenownercannotbeoperator) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `LSP7TokenOwnerCannotBeOperator()` -- Error hash: `0xdab75047` - -::: - -```solidity -error LSP7TokenOwnerCannotBeOperator(); -``` - -reverts when trying to authorize or revoke the token's owner as an operator. - -
- -### NoExtensionFoundForFunctionSelector - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#noextensionfoundforfunctionselector) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `NoExtensionFoundForFunctionSelector(bytes4)` -- Error hash: `0xbb370b2b` - -::: - -```solidity -error NoExtensionFoundForFunctionSelector(bytes4 functionSelector); -``` - -reverts when there is no extension for the function selector being called with - -#### Parameters - -| Name | Type | Description | -| ------------------ | :------: | ----------- | -| `functionSelector` | `bytes4` | - | - -
- -### OperatorAllowanceCannotBeIncreasedFromZero - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#operatorallowancecannotbeincreasedfromzero) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol) -- Error signature: `OperatorAllowanceCannotBeIncreasedFromZero(address)` -- Error hash: `0xcba6e977` - -::: - -```solidity -error OperatorAllowanceCannotBeIncreasedFromZero(address operator); -``` - -Reverts when token owner call [`increaseAllowance`](#increaseallowance) for an operator that does not have any allowance - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `operator` | `address` | - | - -
- -### OwnableCallerNotTheOwner - -:::note References - -- Specification details: [**LSP-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#ownablecallernottheowner) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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-7-DigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-7-DigitalAsset.md#ownablecannotsetzeroaddressasowner) -- Solidity implementation: [`LSP7CompatibleERC20Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.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/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.md b/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.md deleted file mode 100644 index 885463cc7..000000000 --- a/docs/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.md +++ /dev/null @@ -1,2527 +0,0 @@ - - - -# LSP8CompatibleERC721 - -:::info Standard Specifications - -[`LSP-8-IdentifiableDigitalAsset`](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md) - -::: -:::info Solidity implementation - -[`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) - -::: - -LSP8 extension, for compatibility for clients / tools that expect ERC721. - -## 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. - -### fallback - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#fallback) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) - -::: - -```solidity -fallback(bytes calldata callData) external payable returns (bytes memory); -``` - -_The `fallback` function was called with the following amount of native tokens: `msg.value`; and the following calldata: `callData`._ - -Achieves the goal of [LSP-17-ContractExtension] standard by extending the contract to handle calls of functions that do not exist natively, -forwarding the function call to the extension address mapped to the function being called. -This function is executed when: - -- Sending data of length less than 4 bytes to the contract. - -- The first 4 bytes of the calldata do not match any publicly callable functions from the contract ABI. - -- Receiving native tokens - -1. If the data is equal or longer than 4 bytes, the [ERC-725Y] storage is queried with the following data key: [_LSP17_EXTENSION_PREFIX] + `bytes4(msg.sig)` (Check [LSP-2-ERC725YJSONSchema] for encoding the data key) - -- If there is no address stored under the following data key, revert with [`NoExtensionFoundForFunctionSelector(bytes4)`](#noextensionfoundforfunctionselector). The data key relative to `bytes4(0)` is an exception, where no reverts occurs if there is no extension address stored under. This exception is made to allow users to send random data (graffiti) to the account and to be able to react on it. - -- If there is an address, forward the `msg.data` to the extension using the CALL opcode, appending 52 bytes (20 bytes of `msg.sender` and 32 bytes of `msg.value`). Return what the calls returns, or revert if the call failed. - -2. If the data sent to this function is of length less than 4 bytes (not a function selector), revert. - -
- -### receive - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#receive) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) - -::: - -```solidity -receive() external payable; -``` - -_LSP8 contract cannot receive native tokens._ - -Reverts whenever someone tries to send native tokens to a LSP8 contract. - -
- -### approve - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#approve) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `approve(address,uint256)` -- Function selector: `0x095ea7b3` - -::: - -```solidity -function approve(address operator, uint256 tokenId) external nonpayable; -``` - -_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)`. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------- | -| `operator` | `address` | The address to approve for `tokenId`. | -| `tokenId` | `uint256` | The tokenId to approve. | - -
- -### authorizeOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#authorizeoperator) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `authorizeOperator(address,bytes32,bytes)` -- Function selector: `0x86a10ddd` - -::: - -```solidity -function authorizeOperator( - address operator, - bytes32 tokenId, - bytes operatorNotificationData -) external nonpayable; -``` - -Allow an `operator` address to transfer or burn a specific `tokenId` on behalf of its token owner. See [`isOperatorFor`](#isoperatorfor). Notify the operator based on the LSP1-UniversalReceiver standard - -
- -**Emitted events:** - -- LSP7 [`OperatorAuthorizationChanged`](#operatorauthorizationchanged) event. -- ERC721 [`Approval`](#approval) event. - -
- -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ----------------------------------------------- | -| `operator` | `address` | The address to authorize as an operator. | -| `tokenId` | `bytes32` | The token ID operator has access to. | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### balanceOf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#balanceof) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `balanceOf(address)` -- Function selector: `0x70a08231` - -::: - -```solidity -function balanceOf(address tokenOwner) external view returns (uint256); -``` - -Get the number of token IDs owned by `tokenOwner`. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ----------------------- | -| `tokenOwner` | `address` | The address to query \* | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ----------------------------------------------------- | -| `0` | `uint256` | The total number of token IDs that `tokenOwner` owns. | - -
- -### batchCalls - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#batchcalls) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `batchCalls(bytes[])` -- Function selector: `0x6963d438` - -::: - -:::info - -It's not possible to send value along the functions call due to the use of `delegatecall`. - -::: - -```solidity -function batchCalls(bytes[] data) external nonpayable returns (bytes[] results); -``` - -_Executing the following batch of abi-encoded function calls on the contract: `data`._ - -Allows a caller to batch different function calls in one call. Perform a `delegatecall` on self, to call different functions with preserving the context. - -#### Parameters - -| Name | Type | Description | -| ------ | :-------: | -------------------------------------------------------------------- | -| `data` | `bytes[]` | An array of ABI encoded function calls to be called on the contract. | - -#### Returns - -| Name | Type | Description | -| --------- | :-------: | ---------------------------------------------------------------- | -| `results` | `bytes[]` | An array of abi-encoded data returned by the functions executed. | - -
- -### getApproved - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getapproved) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `getApproved(uint256)` -- Function selector: `0x081812fc` - -::: - -```solidity -function getApproved(uint256 tokenId) external view returns (address); -``` - -_Retrieving the address other than the token owner that is approved to transfer tokenId `tokenId` on behalf of its owner._ - -Compatible with ERC721 getApproved. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | --------------------- | -| `tokenId` | `uint256` | The tokenId to query. | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------------------------ | -| `0` | `address` | The address of the operator for `tokenId`. | - -
- -### getData - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getdata) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getdatabatch) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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 | - -
- -### getDataBatchForTokenIds - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getdatabatchfortokenids) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `getDataBatchForTokenIds(bytes32[],bytes32[])` -- Function selector: `0x1d26fce6` - -::: - -```solidity -function getDataBatchForTokenIds( - bytes32[] tokenIds, - bytes32[] dataKeys -) external view returns (bytes[] dataValues); -``` - -_Retrieves data in batch for multiple `tokenId` and `dataKey` pairs._ - -#### Parameters - -| Name | Type | Description | -| ---------- | :---------: | ----------------------------------------------------- | -| `tokenIds` | `bytes32[]` | An array of token IDs. | -| `dataKeys` | `bytes32[]` | An array of data keys corresponding to the token IDs. | - -#### Returns - -| Name | Type | Description | -| ------------ | :-------: | ----------------------------------------------------------------- | -| `dataValues` | `bytes[]` | An array of data values for each pair of `tokenId` and `dataKey`. | - -
- -### getDataForTokenId - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getdatafortokenid) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `getDataForTokenId(bytes32,bytes32)` -- Function selector: `0x16e023b3` - -::: - -```solidity -function getDataForTokenId( - bytes32 tokenId, - bytes32 dataKey -) external view returns (bytes dataValue); -``` - -_Retrieves data for a specific `tokenId` and `dataKey`._ - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ---------------------------------- | -| `tokenId` | `bytes32` | The unique identifier for a token. | -| `dataKey` | `bytes32` | The key for the data to retrieve. | - -#### Returns - -| Name | Type | Description | -| ----------- | :-----: | ----------------------------------------------------------------- | -| `dataValue` | `bytes` | The data value associated with the given `tokenId` and `dataKey`. | - -
- -### getOperatorsOf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getoperatorsof) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `getOperatorsOf(bytes32)` -- Function selector: `0x49a6078d` - -::: - -```solidity -function getOperatorsOf(bytes32 tokenId) external view returns (address[]); -``` - -Returns all `operator` addresses that are allowed to transfer or burn a specific `tokenId` on behalf of its owner. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | -------------------------------------- | -| `tokenId` | `bytes32` | The token ID to get the operators for. | - -#### Returns - -| Name | Type | Description | -| ---- | :---------: | ------------------------------------------------------------------------------------------------------------ | -| `0` | `address[]` | An array of operators allowed to transfer or burn a specific `tokenId`. Requirements - `tokenId` must exist. | - -
- -### isApprovedForAll - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#isapprovedforall) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `isApprovedForAll(address,address)` -- Function selector: `0xe985e9c5` - -::: - -```solidity -function isApprovedForAll( - address tokenOwner, - address operator -) 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` | The tokenOwner address to query. | -| `operator` | `address` | The operator address to query. | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | --------------------------------------------------------------------------- | -| `0` | `bool` | Returns if the `operator` is allowed to manage all of the assets of `owner` | - -
- -### isOperatorFor - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#isoperatorfor) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `isOperatorFor(address,bytes32)` -- Function selector: `0x2a3654a4` - -::: - -```solidity -function isOperatorFor( - address operator, - bytes32 tokenId -) external view returns (bool); -``` - -Returns whether `operator` address is an operator for a given `tokenId`. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------------------------------- | -| `operator` | `address` | The address to query operator status for. | -| `tokenId` | `bytes32` | The token ID to check if `operator` is allowed to operate on. | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | --------------------------------------------------------------------- | -| `0` | `bool` | `true` if `operator` is an operator for `tokenId`, `false` otherwise. | - -
- -### name - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#name) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `name()` -- Function selector: `0x06fdde03` - -::: - -```solidity -function name() external view returns (string); -``` - -Returns the name of the token. For compatibility with clients & tools that expect ERC721. - -#### Returns - -| Name | Type | Description | -| ---- | :------: | --------------------- | -| `0` | `string` | The name of the token | - -
- -### owner - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#owner) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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` | - | - -
- -### ownerOf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#ownerof) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `ownerOf(uint256)` -- Function selector: `0x6352211e` - -::: - -```solidity -function ownerOf(uint256 tokenId) external view returns (address); -``` - -_Retrieving the address that own tokenId `tokenId`._ - -Compatible with ERC721 ownerOf. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | --------------------- | -| `tokenId` | `uint256` | The tokenId to query. | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------- | -| `0` | `address` | The owner of the tokenId. | - -
- -### renounceOwnership - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#renounceownership) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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. - -
- -### revokeOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#revokeoperator) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `revokeOperator(address,bytes32,bool,bytes)` -- Function selector: `0xdb8c9663` - -::: - -```solidity -function revokeOperator( - address operator, - bytes32 tokenId, - bool notify, - bytes operatorNotificationData -) external nonpayable; -``` - -Remove access of `operator` for a given `tokenId`, disallowing it to transfer `tokenId` on behalf of its owner. See also [`isOperatorFor`](#isoperatorfor). - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | -------------------------------------------------------- | -| `operator` | `address` | The address to revoke as an operator. | -| `tokenId` | `bytes32` | The tokenId `operator` is revoked from operating on. | -| `notify` | `bool` | Boolean indicating whether to notify the operator or not | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### safeTransferFrom - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#safetransferfrom) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `safeTransferFrom(address,address,uint256)` -- Function selector: `0x42842e0e` - -::: - -:::info - -This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`. - -::: - -```solidity -function safeTransferFrom( - address from, - address to, - uint256 tokenId -) external nonpayable; -``` - -_Calling `safeTransferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`._ - -Safe Transfer function without optional data from the ERC721 standard interface. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ------------------------ | -| `from` | `address` | The sending address. | -| `to` | `address` | The receiving address. | -| `tokenId` | `uint256` | The tokenId to transfer. | - -
- -### safeTransferFrom - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#safetransferfrom) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `safeTransferFrom(address,address,uint256,bytes)` -- Function selector: `0xb88d4fde` - -::: - -:::info - -This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`. - -::: - -```solidity -function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes data -) external nonpayable; -``` - -_Calling `safeTransferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`._ - -Safe Transfer function with optional data from the ERC721 standard interface. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | -------------------------------------- | -| `from` | `address` | The sending address. | -| `to` | `address` | The receiving address. | -| `tokenId` | `uint256` | The tokenId to transfer. | -| `data` | `bytes` | The data to be sent with the transfer. | - -
- -### setApprovalForAll - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#setapprovalforall) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `setApprovalForAll(address,bool)` -- Function selector: `0xa22cb465` - -::: - -```solidity -function setApprovalForAll(address operator, bool approved) external nonpayable; -``` - -_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` | Address to add to the set of authorized operators. | -| `approved` | `bool` | True if the operator is approved, false to revoke approval. | - -
- -### setData - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#setdata) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#setdatabatch) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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`. | - -
- -### setDataBatchForTokenIds - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#setdatabatchfortokenids) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `setDataBatchForTokenIds(bytes32[],bytes32[],bytes[])` -- Function selector: `0xbe9f0e6f` - -::: - -```solidity -function setDataBatchForTokenIds( - bytes32[] tokenIds, - bytes32[] dataKeys, - bytes[] dataValues -) external nonpayable; -``` - -_Sets data in batch for multiple `tokenId` and `dataKey` pairs._ - -#### Parameters - -| Name | Type | Description | -| ------------ | :---------: | ----------------------------------------------------- | -| `tokenIds` | `bytes32[]` | An array of token IDs. | -| `dataKeys` | `bytes32[]` | An array of data keys corresponding to the token IDs. | -| `dataValues` | `bytes[]` | An array of values to set for the given data keys. | - -
- -### setDataForTokenId - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#setdatafortokenid) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `setDataForTokenId(bytes32,bytes32,bytes)` -- Function selector: `0xd6c1407c` - -::: - -```solidity -function setDataForTokenId( - bytes32 tokenId, - bytes32 dataKey, - bytes dataValue -) external nonpayable; -``` - -_Sets data for a specific `tokenId` and `dataKey`._ - -#### Parameters - -| Name | Type | Description | -| ----------- | :-------: | ---------------------------------------- | -| `tokenId` | `bytes32` | The unique identifier for a token. | -| `dataKey` | `bytes32` | The key for the data to set. | -| `dataValue` | `bytes` | The value to set for the given data key. | - -
- -### supportsInterface - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#supportsinterface) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `supportsInterface(bytes4)` -- Function selector: `0x01ffc9a7` - -::: - -```solidity -function supportsInterface(bytes4 interfaceId) external view returns (bool); -``` - -Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas. - -#### Parameters - -| Name | Type | Description | -| ------------- | :------: | ----------- | -| `interfaceId` | `bytes4` | - | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | - -
- -### symbol - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#symbol) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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. For compatibility with clients & tools that expect ERC721. - -#### Returns - -| Name | Type | Description | -| ---- | :------: | ----------------------- | -| `0` | `string` | The symbol of the token | - -
- -### tokenIdsOf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#tokenidsof) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `tokenIdsOf(address)` -- Function selector: `0xa3b261f2` - -::: - -```solidity -function tokenIdsOf(address tokenOwner) external view returns (bytes32[]); -``` - -Returns the list of token IDs that the `tokenOwner` address owns. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ---------------------------------------------------------- | -| `tokenOwner` | `address` | The address that we want to get the list of token IDs for. | - -#### Returns - -| Name | Type | Description | -| ---- | :---------: | ------------------------------------------------------- | -| `0` | `bytes32[]` | An array of `bytes32[] tokenIds` owned by `tokenOwner`. | - -
- -### tokenOwnerOf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#tokenownerof) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `tokenOwnerOf(bytes32)` -- Function selector: `0x217b2270` - -::: - -```solidity -function tokenOwnerOf(bytes32 tokenId) external view returns (address); -``` - -Returns the list of `tokenIds` for the `tokenOwner` address. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | -------------------------------------------- | -| `tokenId` | `bytes32` | tokenOwner The address to query owned tokens | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ----------------------------------------- | -| `0` | `address` | The owner address of the given `tokenId`. | - -
- -### tokenURI - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#tokenuri) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `tokenURI(uint256)` -- Function selector: `0xc87b56dd` - -::: - -```solidity -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 | -| ---- | :-------: | ----------- | -| `_0` | `uint256` | - | - -#### Returns - -| Name | Type | Description | -| ---- | :------: | -------------- | -| `0` | `string` | The token URI. | - -
- -### totalSupply - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#totalsupply) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `totalSupply()` -- Function selector: `0x18160ddd` - -::: - -```solidity -function totalSupply() external view returns (uint256); -``` - -Returns the number of existing tokens that have been minted in this contract. - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------------ | -| `0` | `uint256` | The number of existing tokens. | - -
- -### transfer - -:::note References - -- 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) -- Function signature: `transfer(address,address,bytes32,bool,bytes)` -- Function selector: `0x511b6952` - -::: - -```solidity -function transfer( - address from, - address to, - bytes32 tokenId, - bool force, - bytes data -) external nonpayable; -``` - -Transfer a given `tokenId` token from the `from` address to the `to` address. If operators are set for a specific `tokenId`, all the operators are revoked after the tokenId have been transferred. The `force` parameter MUST be set to `true` when transferring tokens to Externally Owned Accounts (EOAs) or contracts that do not implement the LSP1 standard. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `from` | `address` | The address that owns the given `tokenId`. | -| `to` | `address` | The address that will receive the `tokenId`. | -| `tokenId` | `bytes32` | The token ID to transfer. | -| `force` | `bool` | When set to `true`, the `to` address CAN be any addres. When set to `false`, the `to` address MUST be a contract that supports the LSP1 UniversalReceiver standard. | -| `data` | `bytes` | Any additional data the caller wants included in the emitted event, and sent in the hooks of the `from` and `to` addresses. | - -
- -### transferBatch - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#transferbatch) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `transferBatch(address[],address[],bytes32[],bool[],bytes[])` -- Function selector: `0x7e87632c` - -::: - -```solidity -function transferBatch( - address[] from, - address[] to, - bytes32[] tokenId, - bool[] force, - bytes[] data -) external nonpayable; -``` - -Transfers multiple tokens at once based on the arrays of `from`, `to` and `tokenId`. If any transfer fails, the whole call will revert. - -#### Parameters - -| Name | Type | Description | -| --------- | :---------: | ----------------------------------------------------------------------------------------------------------------------------------------- | -| `from` | `address[]` | An array of sending addresses. | -| `to` | `address[]` | An array of recipient addresses. | -| `tokenId` | `bytes32[]` | An array of token IDs to transfer. | -| `force` | `bool[]` | When set to `true`, `to` may be any address. When set to `false`, `to` must be a contract that supports the LSP1 standard and not revert. | -| `data` | `bytes[]` | Any additional data the caller wants included in the emitted event, and sent in the hooks to the `from` and `to` addresses. | - -
- -### transferFrom - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#transferfrom) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Function signature: `transferFrom(address,address,uint256)` -- Function selector: `0x23b872dd` - -::: - -:::info - -This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`. - -::: - -```solidity -function transferFrom( - address from, - address to, - uint256 tokenId -) external nonpayable; -``` - -_Calling `transferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`._ - -Transfer functions from the ERC721 standard interface. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ------------------------ | -| `from` | `address` | The sending address. | -| `to` | `address` | The receiving address. | -| `tokenId` | `uint256` | The tokenId to transfer. | - -
- -### transferOwnership - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#transferownership) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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; -``` - -The ERC725Y data key `_LSP8_TOKENID_FORMAT_KEY` cannot be changed -once the identifiable digital asset contract has been deployed. - -
- -### \_isOperatorOrOwner - -```solidity -function _isOperatorOrOwner( - address caller, - bytes32 tokenId -) internal view returns (bool); -``` - -verifies if the `caller` is operator or owner for the `tokenId` - -#### Returns - -| Name | Type | Description | -| ---- | :----: | -------------------------------------------- | -| `0` | `bool` | true if `caller` is either operator or owner | - -
- -### \_revokeOperator - -```solidity -function _revokeOperator( - address operator, - address tokenOwner, - bytes32 tokenId, - bool notified, - bytes operatorNotificationData -) internal nonpayable; -``` - -removes `operator` from the list of operators for the `tokenId` - -
- -### \_clearOperators - -```solidity -function _clearOperators( - address tokenOwner, - bytes32 tokenId -) internal nonpayable; -``` - -revoke all the current operators for a specific `tokenId` token which belongs to `tokenOwner`. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ------------------------------------------------- | -| `tokenOwner` | `address` | The address that is the owner of the `tokenId`. | -| `tokenId` | `bytes32` | The token to remove the associated operators for. | - -
- -### \_exists - -```solidity -function _exists(bytes32 tokenId) internal view returns (bool); -``` - -Returns whether `tokenId` exists. -Tokens start existing when they are minted ([`_mint`](#_mint)), and stop existing when they are burned ([`_burn`](#_burn)). - -
- -### \_existsOrError - -```solidity -function _existsOrError(bytes32 tokenId) internal view; -``` - -When `tokenId` does not exist then revert with an error. - -
- -### \_mint - -```solidity -function _mint( - address to, - bytes32 tokenId, - bool force, - bytes data -) internal nonpayable; -``` - -
- -### \_burn - -```solidity -function _burn(bytes32 tokenId, bytes data) internal nonpayable; -``` - -
- -### \_transfer - -```solidity -function _transfer( - address from, - address to, - bytes32 tokenId, - bool force, - bytes data -) internal nonpayable; -``` - -
- -### \_setDataForTokenId - -```solidity -function _setDataForTokenId( - bytes32 tokenId, - bytes32 dataKey, - bytes dataValue -) internal nonpayable; -``` - -Sets data for a specific `tokenId` and `dataKey` in the ERC725Y storage -The ERC725Y data key is the hash of the `tokenId` and `dataKey` concatenated - -
- -**Emitted events:** - -- [`TokenIdDataChanged`](#tokeniddatachanged) event. - -
- -#### Parameters - -| Name | Type | Description | -| ----------- | :-------: | ---------------------------------------- | -| `tokenId` | `bytes32` | The unique identifier for a token. | -| `dataKey` | `bytes32` | The key for the data to set. | -| `dataValue` | `bytes` | The value to set for the given data key. | - -
- -### \_getDataForTokenId - -```solidity -function _getDataForTokenId( - bytes32 tokenId, - bytes32 dataKey -) internal view returns (bytes dataValues); -``` - -Retrieves data for a specific `tokenId` and `dataKey` from the ERC725Y storage -The ERC725Y data key is the hash of the `tokenId` and `dataKey` concatenated - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ---------------------------------- | -| `tokenId` | `bytes32` | The unique identifier for a token. | -| `dataKey` | `bytes32` | The key for the data to retrieve. | - -#### Returns - -| Name | Type | Description | -| ------------ | :-----: | ----------------------------------------------------------------- | -| `dataValues` | `bytes` | The data value associated with the given `tokenId` and `dataKey`. | - -
- -### \_beforeTokenTransfer - -```solidity -function _beforeTokenTransfer( - address from, - address to, - bytes32 tokenId, - bytes data -) internal nonpayable; -``` - -Hook that is called before any token transfer, including minting and burning. -Allows to run custom logic before updating balances and notifiying sender/recipient by overriding this function. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | -------------------------------------- | -| `from` | `address` | The sender address | -| `to` | `address` | @param tokenId The tokenId to transfer | -| `tokenId` | `bytes32` | The tokenId to transfer | -| `data` | `bytes` | The data sent alongside the transfer | - -
- -### \_afterTokenTransfer - -```solidity -function _afterTokenTransfer( - address from, - address to, - bytes32 tokenId, - bytes data -) internal nonpayable; -``` - -Hook that is called after any token transfer, including minting and burning. -Allows to run custom logic after updating balances, but **before notifiying sender/recipient via LSP1** by overriding this function. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | -------------------------------------- | -| `from` | `address` | The sender address | -| `to` | `address` | @param tokenId The tokenId to transfer | -| `tokenId` | `bytes32` | The tokenId to transfer | -| `data` | `bytes` | The data sent alongside the transfer | - -
- -### \_notifyTokenOperator - -```solidity -function _notifyTokenOperator( - address operator, - bytes lsp1Data -) internal nonpayable; -``` - -Attempt to notify the operator `operator` about the `tokenId` being authorized. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP8_TOKENOPERATOR` as typeId, if `operator` is a contract that supports the LSP1 interface. -If `operator` is an EOA or a contract that does not support the LSP1 interface, nothing will happen and no notification will be sent. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------------------------------------------------ | -| `operator` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `lsp1Data` | `bytes` | the data to be sent to the `operator` address in the `universalReceiver` call. | - -
- -### \_notifyTokenSender - -```solidity -function _notifyTokenSender(address from, bytes lsp1Data) internal nonpayable; -``` - -Attempt to notify the token sender `from` about the `tokenId` being transferred. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP8_TOKENSSENDER` as typeId, if `from` is a contract that supports the LSP1 interface. -If `from` is an EOA or a contract that does not support the LSP1 interface, nothing will happen and no notification will be sent. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------------------------------------------------ | -| `from` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `lsp1Data` | `bytes` | the data to be sent to the `from` address in the `universalReceiver` call. | - -
- -### \_notifyTokenReceiver - -```solidity -function _notifyTokenReceiver( - address to, - bool force, - bytes lsp1Data -) internal nonpayable; -``` - -Attempt to notify the token receiver `to` about the `tokenId` being received. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP8_TOKENSRECIPIENT` as typeId, if `to` is a contract that supports the LSP1 interface. -If `to` is is an EOA or a contract that does not support the LSP1 interface, the behaviour will depend on the `force` boolean flag. - -- if `force` is set to `true`, nothing will happen and no notification will be sent. - -- if `force` is set to `false, the transaction will revert. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | --------------------------------------------------------------------------------------------------- | -| `to` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `force` | `bool` | A boolean that describe if transfer to a `to` address that does not support LSP1 is allowed or not. | -| `lsp1Data` | `bytes` | The data to be sent to the `to` address in the `universalReceiver(...)` call. | - -
- -### \_supportsInterfaceInERC165Extension - -```solidity -function _supportsInterfaceInERC165Extension( - bytes4 interfaceId -) internal view returns (bool); -``` - -Returns whether the interfaceId being checked is supported in the extension of the -[`supportsInterface`](#supportsinterface) selector. -To be used by extendable contracts wishing to extend the ERC165 interfaceIds originally -supported by reading whether the interfaceId queried is supported in the `supportsInterface` -extension if the extension is set, if not it returns false. - -
- -### \_getExtensionAndForwardValue - -```solidity -function _getExtensionAndForwardValue( - bytes4 functionSelector -) internal view returns (address, bool); -``` - -Returns the extension address stored under the following data key: - -- [`_LSP17_EXTENSION_PREFIX`](#_lsp17_extension_prefix) + `` (Check [LSP2-ERC725YJSONSchema] for encoding the data key). - -- If no extension is stored, returns the address(0). - -
- -### \_fallbackLSP17Extendable - -:::info - -The LSP8 Token contract should not hold any native tokens. Any native tokens received by the contract -will be forwarded to the extension address mapped to the selector from `msg.sig`. - -::: - -```solidity -function _fallbackLSP17Extendable( - bytes callData -) internal nonpayable returns (bytes); -``` - -Forwards the call with the received value to an extension mapped to a function selector. -Calls [`_getExtensionAndForwardValue`](#_getextensionandforwardvalue) to get the address of the extension mapped to the function selector being -called on the account. If there is no extension, the address(0) will be returned. -We will always forward the value to the extension, as the LSP8 contract is not supposed to hold any native tokens. -Reverts if there is no extension for the function being called. -If there is an extension for the function selector being called, it calls the extension with the -CALL opcode, passing the [`msg.data`](#msg.data) appended with the 20 bytes of the [`msg.sender`](#msg.sender) and -32 bytes of the [`msg.value`](#msg.value) - -
- -### \_safeTransfer - -```solidity -function _safeTransfer( - address from, - address to, - uint256 tokenId, - bytes data -) internal nonpayable; -``` - -Transfer the `tokenId` from `from` to `to` and check if the `to` recipient address is -a contract that implements the `IERC721Received` interface and return the right magic value. -See [`_checkOnERC721Received`](#_checkonerc721received) for more infos. - -
- -### \_setApprovalForAll - -```solidity -function _setApprovalForAll( - address tokensOwner, - address operator, - bool approved -) internal nonpayable; -``` - -Approve `operator` to operate on all tokens of `tokensOwner`. - -
- -**Emitted events:** - -- [`ApprovalForAll`](#approvalforall) event. - -
- -
- -## Events - -### Approval - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#approval) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Event signature: `Approval(address,address,uint256)` -- Event topic hash: `0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925` - -::: - -```solidity -event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); -``` - -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` | - | -| `approved` **`indexed`** | `address` | - | -| `tokenId` **`indexed`** | `uint256` | - | - -
- -### ApprovalForAll - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#approvalforall) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Event signature: `ApprovalForAll(address,address,bool)` -- Event topic hash: `0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31` - -::: - -```solidity -event ApprovalForAll(address indexed owner, address indexed operator, bool approved); -``` - -Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to `approved`. - -#### Parameters - -| Name | Type | Description | -| ------------------------ | :-------: | ----------- | -| `owner` **`indexed`** | `address` | - | -| `operator` **`indexed`** | `address` | - | -| `approved` | `bool` | - | - -
- -### DataChanged - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#datachanged) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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. | - -
- -### OperatorAuthorizationChanged - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#operatorauthorizationchanged) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Event signature: `OperatorAuthorizationChanged(address,address,bytes32,bytes)` -- Event topic hash: `0x1b1b58aa2ec0cec2228b2d37124556d41f5a1f7b12f089171f896cc236671215` - -::: - -```solidity -event OperatorAuthorizationChanged(address indexed operator, address indexed tokenOwner, bytes32 indexed tokenId, bytes operatorNotificationData); -``` - -Emitted when `tokenOwner` enables `operator` to transfer or burn the `tokenId`. - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | -------------------------------------------------------------------- | -| `operator` **`indexed`** | `address` | The address authorized as an operator. | -| `tokenOwner` **`indexed`** | `address` | The owner of the `tokenId`. | -| `tokenId` **`indexed`** | `bytes32` | The tokenId `operator` address has access on behalf of `tokenOwner`. | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### OperatorRevoked - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#operatorrevoked) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Event signature: `OperatorRevoked(address,address,bytes32,bool,bytes)` -- Event topic hash: `0xc78cd419d6136f9f1c1c6aec1d3fae098cffaf8bc86314a8f2685e32fe574e3c` - -::: - -```solidity -event OperatorRevoked(address indexed operator, address indexed tokenOwner, bytes32 indexed tokenId, bool notified, bytes operatorNotificationData); -``` - -Emitted when `tokenOwner` disables `operator` to transfer or burn `tokenId` on its behalf. - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ---------------------------------------------------------------------------------- | -| `operator` **`indexed`** | `address` | The address revoked from the operator array ([`getOperatorsOf`](#getoperatorsof)). | -| `tokenOwner` **`indexed`** | `address` | The owner of the `tokenId`. | -| `tokenId` **`indexed`** | `bytes32` | The tokenId `operator` is revoked from operating on. | -| `notified` | `bool` | Bool indicating whether the operator has been notified or not | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### OwnershipTransferred - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#ownershiptransferred) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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` | - | - -
- -### TokenIdDataChanged - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#tokeniddatachanged) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Event signature: `TokenIdDataChanged(bytes32,bytes32,bytes)` -- Event topic hash: `0xa6e4251f855f750545fe414f120db91c76b88def14d120969e5bb2d3f05debbb` - -::: - -```solidity -event TokenIdDataChanged(bytes32 indexed tokenId, bytes32 indexed dataKey, bytes dataValue); -``` - -Emitted when setting data for `tokenId`. - -#### Parameters - -| Name | Type | Description | -| ----------------------- | :-------: | -------------------------------------------- | -| `tokenId` **`indexed`** | `bytes32` | The tokenId which data is set for. | -| `dataKey` **`indexed`** | `bytes32` | The data key for which a bytes value is set. | -| `dataValue` | `bytes` | The value to set for the given data key. | - -
- -### Transfer - -:::note References - -- 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` - -::: - -```solidity -event Transfer(address operator, address indexed from, address indexed to, bytes32 indexed tokenId, bool force, bytes data); -``` - -Emitted when `tokenId` token is transferred from the `from` to the `to` address. - -#### 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. | - -
- -### Transfer - -:::note References - -- 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` - -::: - -```solidity -event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); -``` - -Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. - -#### Parameters - -| Name | Type | Description | -| ----------------------- | :-------: | ----------- | -| `from` **`indexed`** | `address` | - | -| `to` **`indexed`** | `address` | - | -| `tokenId` **`indexed`** | `uint256` | - | - -
- -## Errors - -### ERC725Y_DataKeysValuesEmptyArray - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#erc725y_datakeysvaluesemptyarray) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#erc725y_datakeysvalueslengthmismatch) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#erc725y_msgvaluedisallowed) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `ERC725Y_MsgValueDisallowed()` -- Error hash: `0xf36ba737` - -::: - -```solidity -error ERC725Y_MsgValueDisallowed(); -``` - -Reverts when sending value to the [`setData`](#setdata) or [`setDataBatch`](#setdatabatch) function. - -
- -### InvalidExtensionAddress - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#invalidextensionaddress) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `InvalidExtensionAddress(bytes)` -- Error hash: `0x42bfe79f` - -::: - -```solidity -error InvalidExtensionAddress(bytes storedData); -``` - -reverts when the bytes retrieved from the LSP17 data key is not a valid address (not 20 bytes) - -#### Parameters - -| Name | Type | Description | -| ------------ | :-----: | ----------- | -| `storedData` | `bytes` | - | - -
- -### InvalidFunctionSelector - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#invalidfunctionselector) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `InvalidFunctionSelector(bytes)` -- Error hash: `0xe5099ee3` - -::: - -```solidity -error InvalidFunctionSelector(bytes data); -``` - -reverts when the contract is called with a function selector not valid (less than 4 bytes of data) - -#### Parameters - -| Name | Type | Description | -| ------ | :-----: | ----------- | -| `data` | `bytes` | - | - -
- -### LSP4TokenNameNotEditable - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp4tokennamenoteditable) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP4TokenNameNotEditable()` -- Error hash: `0x85c169bd` - -::: - -```solidity -error LSP4TokenNameNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenName` after the digital asset contract has been deployed / initialized. The `LSP4TokenName` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor/initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP4TokenSymbolNotEditable - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp4tokensymbolnoteditable) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP4TokenSymbolNotEditable()` -- Error hash: `0x76755b38` - -::: - -```solidity -error LSP4TokenSymbolNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenSymbol` after the digital asset contract has been deployed / initialized. The `LSP4TokenSymbol` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor/initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP4TokenTypeNotEditable - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp4tokentypenoteditable) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP4TokenTypeNotEditable()` -- Error hash: `0x4ef6d7fb` - -::: - -```solidity -error LSP4TokenTypeNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenType` after the digital asset contract has been deployed / initialized. The `LSP4TokenType` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor / initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP8BatchCallFailed - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8batchcallfailed) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8BatchCallFailed(uint256)` -- Error hash: `0x234eb819` - -::: - -```solidity -error LSP8BatchCallFailed(uint256 callIndex); -``` - -_Batch call failed._ - -Reverts when a batch call failed. - -#### Parameters - -| Name | Type | Description | -| ----------- | :-------: | ----------- | -| `callIndex` | `uint256` | - | - -
- -### LSP8CannotSendToAddressZero - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotsendtoaddresszero) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8CannotSendToAddressZero()` -- Error hash: `0x24ecef4d` - -::: - -```solidity -error LSP8CannotSendToAddressZero(); -``` - -Reverts when trying to send token to the zero address. - -
- -### LSP8CannotSendToSelf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotsendtoself) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8CannotSendToSelf()` -- Error hash: `0x5d67d6c1` - -::: - -```solidity -error LSP8CannotSendToSelf(); -``` - -Reverts when specifying the same address for `from` and `to` in a token transfer. - -
- -### LSP8CannotUseAddressZeroAsOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotuseaddresszeroasoperator) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8CannotUseAddressZeroAsOperator()` -- Error hash: `0x9577b8b3` - -::: - -```solidity -error LSP8CannotUseAddressZeroAsOperator(); -``` - -Reverts when trying to set the zero address as an operator. - -
- -### LSP8InvalidTransferBatch - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8invalidtransferbatch) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8InvalidTransferBatch()` -- Error hash: `0x93a83119` - -::: - -```solidity -error LSP8InvalidTransferBatch(); -``` - -Reverts when the parameters used for `transferBatch` have different lengths. - -
- -### LSP8NonExistentTokenId - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8nonexistenttokenid) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8NonExistentTokenId(bytes32)` -- Error hash: `0xae8f9a36` - -::: - -```solidity -error LSP8NonExistentTokenId(bytes32 tokenId); -``` - -Reverts when `tokenId` has not been minted. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ----------- | -| `tokenId` | `bytes32` | - | - -
- -### LSP8NonExistingOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8nonexistingoperator) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8NonExistingOperator(address,bytes32)` -- Error hash: `0x4aa31a8c` - -::: - -```solidity -error LSP8NonExistingOperator(address operator, bytes32 tokenId); -``` - -Reverts when `operator` is not an operator for the `tokenId`. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `operator` | `address` | - | -| `tokenId` | `bytes32` | - | - -
- -### LSP8NotTokenOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8nottokenoperator) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8NotTokenOperator(bytes32,address)` -- Error hash: `0x1294d2a9` - -::: - -```solidity -error LSP8NotTokenOperator(bytes32 tokenId, address caller); -``` - -Reverts when `caller` is not an allowed operator for `tokenId`. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ----------- | -| `tokenId` | `bytes32` | - | -| `caller` | `address` | - | - -
- -### LSP8NotTokenOwner - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8nottokenowner) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8NotTokenOwner(address,bytes32,address)` -- Error hash: `0x5b271ea2` - -::: - -```solidity -error LSP8NotTokenOwner(address tokenOwner, bytes32 tokenId, address caller); -``` - -Reverts when `caller` is not the `tokenOwner` of the `tokenId`. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ----------- | -| `tokenOwner` | `address` | - | -| `tokenId` | `bytes32` | - | -| `caller` | `address` | - | - -
- -### LSP8NotifyTokenReceiverContractMissingLSP1Interface - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8notifytokenreceivercontractmissinglsp1interface) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8NotifyTokenReceiverContractMissingLSP1Interface(address)` -- Error hash: `0x4349776d` - -::: - -```solidity -error LSP8NotifyTokenReceiverContractMissingLSP1Interface( - address tokenReceiver -); -``` - -Reverts if the `tokenReceiver` does not implement LSP1 when minting or transferring tokens with `bool force` set as `false`. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ----------- | -| `tokenReceiver` | `address` | - | - -
- -### LSP8NotifyTokenReceiverIsEOA - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8notifytokenreceiveriseoa) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8NotifyTokenReceiverIsEOA(address)` -- Error hash: `0x03173137` - -::: - -```solidity -error LSP8NotifyTokenReceiverIsEOA(address tokenReceiver); -``` - -Reverts if the `tokenReceiver` is an EOA when minting or transferring tokens with `bool force` set as `false`. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ----------- | -| `tokenReceiver` | `address` | - | - -
- -### LSP8OperatorAlreadyAuthorized - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8operatoralreadyauthorized) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8OperatorAlreadyAuthorized(address,bytes32)` -- Error hash: `0xa7626b68` - -::: - -```solidity -error LSP8OperatorAlreadyAuthorized(address operator, bytes32 tokenId); -``` - -Reverts when `operator` is already authorized for the `tokenId`. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `operator` | `address` | - | -| `tokenId` | `bytes32` | - | - -
- -### LSP8TokenContractCannotHoldValue - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokencontractcannotholdvalue) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8TokenContractCannotHoldValue()` -- Error hash: `0x61f49442` - -::: - -```solidity -error LSP8TokenContractCannotHoldValue(); -``` - -_LSP8 contract cannot receive native tokens._ - -Error occurs when sending native tokens to the LSP8 contract without sending any data. E.g. Sending value without passing a bytes4 function selector to call a LSP17 Extension. - -
- -### LSP8TokenIdFormatNotEditable - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenidformatnoteditable) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8TokenIdFormatNotEditable()` -- Error hash: `0x3664800a` - -::: - -```solidity -error LSP8TokenIdFormatNotEditable(); -``` - -Reverts when trying to edit the data key `LSP8TokenIdFormat` after the identifiable digital asset contract has been deployed. The `LSP8TokenIdFormat` data key is located inside the ERC725Y Data key-value store of the identifiable digital asset contract. It can be set only once inside the constructor/initializer when the identifiable digital asset contract is being deployed. - -
- -### LSP8TokenIdsDataEmptyArray - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenidsdataemptyarray) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8TokenIdsDataEmptyArray()` -- Error hash: `0x80c98305` - -::: - -```solidity -error LSP8TokenIdsDataEmptyArray(); -``` - -Reverts when empty arrays is passed to the function - -
- -### LSP8TokenIdsDataLengthMismatch - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenidsdatalengthmismatch) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8TokenIdsDataLengthMismatch()` -- Error hash: `0x2fa71dfe` - -::: - -```solidity -error LSP8TokenIdsDataLengthMismatch(); -``` - -Reverts when the length of the token IDs data arrays is not equal - -
- -### LSP8TokenOwnerCannotBeOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenownercannotbeoperator) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `LSP8TokenOwnerCannotBeOperator()` -- Error hash: `0x89fdad62` - -::: - -```solidity -error LSP8TokenOwnerCannotBeOperator(); -``` - -Reverts when trying to authorize or revoke the token's owner as an operator. - -
- -### NoExtensionFoundForFunctionSelector - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#noextensionfoundforfunctionselector) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol) -- Error signature: `NoExtensionFoundForFunctionSelector(bytes4)` -- Error hash: `0xbb370b2b` - -::: - -```solidity -error NoExtensionFoundForFunctionSelector(bytes4 functionSelector); -``` - -reverts when there is no extension for the function selector being called with - -#### Parameters - -| Name | Type | Description | -| ------------------ | :------: | ----------- | -| `functionSelector` | `bytes4` | - | - -
- -### OwnableCallerNotTheOwner - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#ownablecallernottheowner) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#ownablecannotsetzeroaddressasowner) -- Solidity implementation: [`LSP8CompatibleERC721.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.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/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.md b/docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.md deleted file mode 100644 index 01b0bfd1f..000000000 --- a/docs/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.md +++ /dev/null @@ -1,2596 +0,0 @@ - - - -# LSP8CompatibleERC721Mintable - -:::info Standard Specifications - -[`LSP-8-IdentifiableDigitalAsset`](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md) - -::: -:::info Solidity implementation - -[`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) - -::: - -> LSP8CompatibleERC721Mintable deployable preset contract with a public [`mint`](#mint) function callable only by the contract [`owner`](#owner). - -## 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. - -### constructor - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#constructor) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) - -::: - -```solidity -constructor( - string name_, - string symbol_, - address newOwner_, - uint256 lsp4TokenType_, - uint256 lsp8TokenIdFormat_ -); -``` - -_Deploying a `LSP8CompatibleERC721Mintable` token contract with: token name = `name_`, token symbol = `symbol_`, and address `newOwner_` as the token contract owner._ - -#### Parameters - -| Name | Type | Description | -| -------------------- | :-------: | ---------------------------------------------------------------------------------------------------- | -| `name_` | `string` | The name of the token. | -| `symbol_` | `string` | The symbol of the token. | -| `newOwner_` | `address` | The owner of the token contract. | -| `lsp4TokenType_` | `uint256` | The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection). | -| `lsp8TokenIdFormat_` | `uint256` | The format of tokenIds (= NFTs) that this contract will create. | - -
- -### fallback - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#fallback) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) - -::: - -```solidity -fallback() external payable; -``` - -
- -### receive - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#receive) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) - -::: - -```solidity -receive() external payable; -``` - -
- -### approve - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#approve) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `approve(address,uint256)` -- Function selector: `0x095ea7b3` - -::: - -```solidity -function approve(address operator, uint256 tokenId) external nonpayable; -``` - -_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)`. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------- | -| `operator` | `address` | The address to approve for `tokenId`. | -| `tokenId` | `uint256` | The tokenId to approve. | - -
- -### authorizeOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#authorizeoperator) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `authorizeOperator(address,bytes32,bytes)` -- Function selector: `0x86a10ddd` - -::: - -```solidity -function authorizeOperator( - address operator, - bytes32 tokenId, - bytes operatorNotificationData -) external nonpayable; -``` - -Allow an `operator` address to transfer or burn a specific `tokenId` on behalf of its token owner. See [`isOperatorFor`](#isoperatorfor). Notify the operator based on the LSP1-UniversalReceiver standard - -
- -**Emitted events:** - -- LSP7 [`OperatorAuthorizationChanged`](#operatorauthorizationchanged) event. -- ERC721 [`Approval`](#approval) event. - -
- -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ----------------------------------------------- | -| `operator` | `address` | The address to authorize as an operator. | -| `tokenId` | `bytes32` | The token ID operator has access to. | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### balanceOf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#balanceof) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `balanceOf(address)` -- Function selector: `0x70a08231` - -::: - -```solidity -function balanceOf(address tokenOwner) external view returns (uint256); -``` - -Get the number of token IDs owned by `tokenOwner`. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ----------------------- | -| `tokenOwner` | `address` | The address to query \* | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ----------------------------------------------------- | -| `0` | `uint256` | The total number of token IDs that `tokenOwner` owns. | - -
- -### batchCalls - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#batchcalls) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `batchCalls(bytes[])` -- Function selector: `0x6963d438` - -::: - -:::info - -It's not possible to send value along the functions call due to the use of `delegatecall`. - -::: - -```solidity -function batchCalls(bytes[] data) external nonpayable returns (bytes[] results); -``` - -_Executing the following batch of abi-encoded function calls on the contract: `data`._ - -Allows a caller to batch different function calls in one call. Perform a `delegatecall` on self, to call different functions with preserving the context. - -#### Parameters - -| Name | Type | Description | -| ------ | :-------: | -------------------------------------------------------------------- | -| `data` | `bytes[]` | An array of ABI encoded function calls to be called on the contract. | - -#### Returns - -| Name | Type | Description | -| --------- | :-------: | ---------------------------------------------------------------- | -| `results` | `bytes[]` | An array of abi-encoded data returned by the functions executed. | - -
- -### getApproved - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getapproved) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `getApproved(uint256)` -- Function selector: `0x081812fc` - -::: - -```solidity -function getApproved(uint256 tokenId) external view returns (address); -``` - -_Retrieving the address other than the token owner that is approved to transfer tokenId `tokenId` on behalf of its owner._ - -Compatible with ERC721 getApproved. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | --------------------- | -| `tokenId` | `uint256` | The tokenId to query. | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------------------------ | -| `0` | `address` | The address of the operator for `tokenId`. | - -
- -### getData - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getdata) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getdatabatch) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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 | - -
- -### getDataBatchForTokenIds - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getdatabatchfortokenids) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `getDataBatchForTokenIds(bytes32[],bytes32[])` -- Function selector: `0x1d26fce6` - -::: - -```solidity -function getDataBatchForTokenIds( - bytes32[] tokenIds, - bytes32[] dataKeys -) external view returns (bytes[] dataValues); -``` - -_Retrieves data in batch for multiple `tokenId` and `dataKey` pairs._ - -#### Parameters - -| Name | Type | Description | -| ---------- | :---------: | ----------------------------------------------------- | -| `tokenIds` | `bytes32[]` | An array of token IDs. | -| `dataKeys` | `bytes32[]` | An array of data keys corresponding to the token IDs. | - -#### Returns - -| Name | Type | Description | -| ------------ | :-------: | ----------------------------------------------------------------- | -| `dataValues` | `bytes[]` | An array of data values for each pair of `tokenId` and `dataKey`. | - -
- -### getDataForTokenId - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getdatafortokenid) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `getDataForTokenId(bytes32,bytes32)` -- Function selector: `0x16e023b3` - -::: - -```solidity -function getDataForTokenId( - bytes32 tokenId, - bytes32 dataKey -) external view returns (bytes dataValue); -``` - -_Retrieves data for a specific `tokenId` and `dataKey`._ - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ---------------------------------- | -| `tokenId` | `bytes32` | The unique identifier for a token. | -| `dataKey` | `bytes32` | The key for the data to retrieve. | - -#### Returns - -| Name | Type | Description | -| ----------- | :-----: | ----------------------------------------------------------------- | -| `dataValue` | `bytes` | The data value associated with the given `tokenId` and `dataKey`. | - -
- -### getOperatorsOf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#getoperatorsof) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `getOperatorsOf(bytes32)` -- Function selector: `0x49a6078d` - -::: - -```solidity -function getOperatorsOf(bytes32 tokenId) external view returns (address[]); -``` - -Returns all `operator` addresses that are allowed to transfer or burn a specific `tokenId` on behalf of its owner. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | -------------------------------------- | -| `tokenId` | `bytes32` | The token ID to get the operators for. | - -#### Returns - -| Name | Type | Description | -| ---- | :---------: | ------------------------------------------------------------------------------------------------------------ | -| `0` | `address[]` | An array of operators allowed to transfer or burn a specific `tokenId`. Requirements - `tokenId` must exist. | - -
- -### isApprovedForAll - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#isapprovedforall) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `isApprovedForAll(address,address)` -- Function selector: `0xe985e9c5` - -::: - -```solidity -function isApprovedForAll( - address tokenOwner, - address operator -) 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` | The tokenOwner address to query. | -| `operator` | `address` | The operator address to query. | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | --------------------------------------------------------------------------- | -| `0` | `bool` | Returns if the `operator` is allowed to manage all of the assets of `owner` | - -
- -### isOperatorFor - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#isoperatorfor) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `isOperatorFor(address,bytes32)` -- Function selector: `0x2a3654a4` - -::: - -```solidity -function isOperatorFor( - address operator, - bytes32 tokenId -) external view returns (bool); -``` - -Returns whether `operator` address is an operator for a given `tokenId`. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------------------------------- | -| `operator` | `address` | The address to query operator status for. | -| `tokenId` | `bytes32` | The token ID to check if `operator` is allowed to operate on. | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | --------------------------------------------------------------------- | -| `0` | `bool` | `true` if `operator` is an operator for `tokenId`, `false` otherwise. | - -
- -### mint - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#mint) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `mint(address,bytes32,bool,bytes)` -- Function selector: `0xaf255b61` - -::: - -```solidity -function mint( - address to, - bytes32 tokenId, - bool force, - bytes data -) external nonpayable; -``` - -_Minting tokenId `tokenId` for address `to` with the additional data `data` (Note: allow non-LSP1 recipient is set to `force`)._ - -Public [`_mint`](#_mint) function only callable by the [`owner`](#owner). - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ------------------------------------------------------------------------------------------------------------------------------ | -| `to` | `address` | The address that will receive the minted `tokenId`. | -| `tokenId` | `bytes32` | The tokenId to mint. | -| `force` | `bool` | Set to `false` to ensure that you are minting for a recipient that implements LSP1, `false` otherwise for forcing the minting. | -| `data` | `bytes` | Any addition data to be sent alongside the minting. | - -
- -### name - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#name) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `name()` -- Function selector: `0x06fdde03` - -::: - -```solidity -function name() external view returns (string); -``` - -Returns the name of the token. For compatibility with clients & tools that expect ERC721. - -#### Returns - -| Name | Type | Description | -| ---- | :------: | --------------------- | -| `0` | `string` | The name of the token | - -
- -### owner - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#owner) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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` | - | - -
- -### ownerOf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#ownerof) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `ownerOf(uint256)` -- Function selector: `0x6352211e` - -::: - -```solidity -function ownerOf(uint256 tokenId) external view returns (address); -``` - -_Retrieving the address that own tokenId `tokenId`._ - -Compatible with ERC721 ownerOf. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | --------------------- | -| `tokenId` | `uint256` | The tokenId to query. | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------- | -| `0` | `address` | The owner of the tokenId. | - -
- -### renounceOwnership - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#renounceownership) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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. - -
- -### revokeOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#revokeoperator) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `revokeOperator(address,bytes32,bool,bytes)` -- Function selector: `0xdb8c9663` - -::: - -```solidity -function revokeOperator( - address operator, - bytes32 tokenId, - bool notify, - bytes operatorNotificationData -) external nonpayable; -``` - -Remove access of `operator` for a given `tokenId`, disallowing it to transfer `tokenId` on behalf of its owner. See also [`isOperatorFor`](#isoperatorfor). - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | -------------------------------------------------------- | -| `operator` | `address` | The address to revoke as an operator. | -| `tokenId` | `bytes32` | The tokenId `operator` is revoked from operating on. | -| `notify` | `bool` | Boolean indicating whether to notify the operator or not | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### safeTransferFrom - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#safetransferfrom) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `safeTransferFrom(address,address,uint256)` -- Function selector: `0x42842e0e` - -::: - -:::info - -This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`. - -::: - -```solidity -function safeTransferFrom( - address from, - address to, - uint256 tokenId -) external nonpayable; -``` - -_Calling `safeTransferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`._ - -Safe Transfer function without optional data from the ERC721 standard interface. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ------------------------ | -| `from` | `address` | The sending address. | -| `to` | `address` | The receiving address. | -| `tokenId` | `uint256` | The tokenId to transfer. | - -
- -### safeTransferFrom - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#safetransferfrom) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `safeTransferFrom(address,address,uint256,bytes)` -- Function selector: `0xb88d4fde` - -::: - -:::info - -This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`. - -::: - -```solidity -function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes data -) external nonpayable; -``` - -_Calling `safeTransferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`._ - -Safe Transfer function with optional data from the ERC721 standard interface. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | -------------------------------------- | -| `from` | `address` | The sending address. | -| `to` | `address` | The receiving address. | -| `tokenId` | `uint256` | The tokenId to transfer. | -| `data` | `bytes` | The data to be sent with the transfer. | - -
- -### setApprovalForAll - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#setapprovalforall) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `setApprovalForAll(address,bool)` -- Function selector: `0xa22cb465` - -::: - -```solidity -function setApprovalForAll(address operator, bool approved) external nonpayable; -``` - -_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` | Address to add to the set of authorized operators. | -| `approved` | `bool` | True if the operator is approved, false to revoke approval. | - -
- -### setData - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#setdata) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#setdatabatch) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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`. | - -
- -### setDataBatchForTokenIds - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#setdatabatchfortokenids) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `setDataBatchForTokenIds(bytes32[],bytes32[],bytes[])` -- Function selector: `0xbe9f0e6f` - -::: - -```solidity -function setDataBatchForTokenIds( - bytes32[] tokenIds, - bytes32[] dataKeys, - bytes[] dataValues -) external nonpayable; -``` - -_Sets data in batch for multiple `tokenId` and `dataKey` pairs._ - -#### Parameters - -| Name | Type | Description | -| ------------ | :---------: | ----------------------------------------------------- | -| `tokenIds` | `bytes32[]` | An array of token IDs. | -| `dataKeys` | `bytes32[]` | An array of data keys corresponding to the token IDs. | -| `dataValues` | `bytes[]` | An array of values to set for the given data keys. | - -
- -### setDataForTokenId - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#setdatafortokenid) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `setDataForTokenId(bytes32,bytes32,bytes)` -- Function selector: `0xd6c1407c` - -::: - -```solidity -function setDataForTokenId( - bytes32 tokenId, - bytes32 dataKey, - bytes dataValue -) external nonpayable; -``` - -_Sets data for a specific `tokenId` and `dataKey`._ - -#### Parameters - -| Name | Type | Description | -| ----------- | :-------: | ---------------------------------------- | -| `tokenId` | `bytes32` | The unique identifier for a token. | -| `dataKey` | `bytes32` | The key for the data to set. | -| `dataValue` | `bytes` | The value to set for the given data key. | - -
- -### supportsInterface - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#supportsinterface) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `supportsInterface(bytes4)` -- Function selector: `0x01ffc9a7` - -::: - -```solidity -function supportsInterface(bytes4 interfaceId) external view returns (bool); -``` - -Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas. - -#### Parameters - -| Name | Type | Description | -| ------------- | :------: | ----------- | -| `interfaceId` | `bytes4` | - | - -#### Returns - -| Name | Type | Description | -| ---- | :----: | ----------- | -| `0` | `bool` | - | - -
- -### symbol - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#symbol) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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. For compatibility with clients & tools that expect ERC721. - -#### Returns - -| Name | Type | Description | -| ---- | :------: | ----------------------- | -| `0` | `string` | The symbol of the token | - -
- -### tokenIdsOf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#tokenidsof) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `tokenIdsOf(address)` -- Function selector: `0xa3b261f2` - -::: - -```solidity -function tokenIdsOf(address tokenOwner) external view returns (bytes32[]); -``` - -Returns the list of token IDs that the `tokenOwner` address owns. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ---------------------------------------------------------- | -| `tokenOwner` | `address` | The address that we want to get the list of token IDs for. | - -#### Returns - -| Name | Type | Description | -| ---- | :---------: | ------------------------------------------------------- | -| `0` | `bytes32[]` | An array of `bytes32[] tokenIds` owned by `tokenOwner`. | - -
- -### tokenOwnerOf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#tokenownerof) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `tokenOwnerOf(bytes32)` -- Function selector: `0x217b2270` - -::: - -```solidity -function tokenOwnerOf(bytes32 tokenId) external view returns (address); -``` - -Returns the list of `tokenIds` for the `tokenOwner` address. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | -------------------------------------------- | -| `tokenId` | `bytes32` | tokenOwner The address to query owned tokens | - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ----------------------------------------- | -| `0` | `address` | The owner address of the given `tokenId`. | - -
- -### tokenURI - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#tokenuri) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `tokenURI(uint256)` -- Function selector: `0xc87b56dd` - -::: - -```solidity -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 | -| ---- | :-------: | ----------- | -| `_0` | `uint256` | - | - -#### Returns - -| Name | Type | Description | -| ---- | :------: | -------------- | -| `0` | `string` | The token URI. | - -
- -### totalSupply - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#totalsupply) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `totalSupply()` -- Function selector: `0x18160ddd` - -::: - -```solidity -function totalSupply() external view returns (uint256); -``` - -Returns the number of existing tokens that have been minted in this contract. - -#### Returns - -| Name | Type | Description | -| ---- | :-------: | ------------------------------ | -| `0` | `uint256` | The number of existing tokens. | - -
- -### transfer - -:::note References - -- 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) -- Function signature: `transfer(address,address,bytes32,bool,bytes)` -- Function selector: `0x511b6952` - -::: - -```solidity -function transfer( - address from, - address to, - bytes32 tokenId, - bool force, - bytes data -) external nonpayable; -``` - -Transfer a given `tokenId` token from the `from` address to the `to` address. If operators are set for a specific `tokenId`, all the operators are revoked after the tokenId have been transferred. The `force` parameter MUST be set to `true` when transferring tokens to Externally Owned Accounts (EOAs) or contracts that do not implement the LSP1 standard. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `from` | `address` | The address that owns the given `tokenId`. | -| `to` | `address` | The address that will receive the `tokenId`. | -| `tokenId` | `bytes32` | The token ID to transfer. | -| `force` | `bool` | When set to `true`, the `to` address CAN be any addres. When set to `false`, the `to` address MUST be a contract that supports the LSP1 UniversalReceiver standard. | -| `data` | `bytes` | Any additional data the caller wants included in the emitted event, and sent in the hooks of the `from` and `to` addresses. | - -
- -### transferBatch - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#transferbatch) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `transferBatch(address[],address[],bytes32[],bool[],bytes[])` -- Function selector: `0x7e87632c` - -::: - -```solidity -function transferBatch( - address[] from, - address[] to, - bytes32[] tokenId, - bool[] force, - bytes[] data -) external nonpayable; -``` - -Transfers multiple tokens at once based on the arrays of `from`, `to` and `tokenId`. If any transfer fails, the whole call will revert. - -#### Parameters - -| Name | Type | Description | -| --------- | :---------: | ----------------------------------------------------------------------------------------------------------------------------------------- | -| `from` | `address[]` | An array of sending addresses. | -| `to` | `address[]` | An array of recipient addresses. | -| `tokenId` | `bytes32[]` | An array of token IDs to transfer. | -| `force` | `bool[]` | When set to `true`, `to` may be any address. When set to `false`, `to` must be a contract that supports the LSP1 standard and not revert. | -| `data` | `bytes[]` | Any additional data the caller wants included in the emitted event, and sent in the hooks to the `from` and `to` addresses. | - -
- -### transferFrom - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#transferfrom) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Function signature: `transferFrom(address,address,uint256)` -- Function selector: `0x23b872dd` - -::: - -:::info - -This function sets the `force` parameter to `true` so that EOAs and any contract can receive the `tokenId`. - -::: - -```solidity -function transferFrom( - address from, - address to, - uint256 tokenId -) external nonpayable; -``` - -_Calling `transferFrom` function to transfer tokenId `tokenId` from address `from` to address `to`._ - -Transfer functions from the ERC721 standard interface. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ------------------------ | -| `from` | `address` | The sending address. | -| `to` | `address` | The receiving address. | -| `tokenId` | `uint256` | The tokenId to transfer. | - -
- -### transferOwnership - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#transferownership) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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; -``` - -The ERC725Y data key `_LSP8_TOKENID_FORMAT_KEY` cannot be changed -once the identifiable digital asset contract has been deployed. - -
- -### \_isOperatorOrOwner - -```solidity -function _isOperatorOrOwner( - address caller, - bytes32 tokenId -) internal view returns (bool); -``` - -verifies if the `caller` is operator or owner for the `tokenId` - -#### Returns - -| Name | Type | Description | -| ---- | :----: | -------------------------------------------- | -| `0` | `bool` | true if `caller` is either operator or owner | - -
- -### \_revokeOperator - -```solidity -function _revokeOperator( - address operator, - address tokenOwner, - bytes32 tokenId, - bool notified, - bytes operatorNotificationData -) internal nonpayable; -``` - -removes `operator` from the list of operators for the `tokenId` - -
- -### \_clearOperators - -```solidity -function _clearOperators( - address tokenOwner, - bytes32 tokenId -) internal nonpayable; -``` - -revoke all the current operators for a specific `tokenId` token which belongs to `tokenOwner`. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ------------------------------------------------- | -| `tokenOwner` | `address` | The address that is the owner of the `tokenId`. | -| `tokenId` | `bytes32` | The token to remove the associated operators for. | - -
- -### \_exists - -```solidity -function _exists(bytes32 tokenId) internal view returns (bool); -``` - -Returns whether `tokenId` exists. -Tokens start existing when they are minted ([`_mint`](#_mint)), and stop existing when they are burned ([`_burn`](#_burn)). - -
- -### \_existsOrError - -```solidity -function _existsOrError(bytes32 tokenId) internal view; -``` - -When `tokenId` does not exist then revert with an error. - -
- -### \_mint - -```solidity -function _mint( - address to, - bytes32 tokenId, - bool force, - bytes data -) internal nonpayable; -``` - -
- -### \_burn - -```solidity -function _burn(bytes32 tokenId, bytes data) internal nonpayable; -``` - -
- -### \_transfer - -```solidity -function _transfer( - address from, - address to, - bytes32 tokenId, - bool force, - bytes data -) internal nonpayable; -``` - -
- -### \_setDataForTokenId - -```solidity -function _setDataForTokenId( - bytes32 tokenId, - bytes32 dataKey, - bytes dataValue -) internal nonpayable; -``` - -Sets data for a specific `tokenId` and `dataKey` in the ERC725Y storage -The ERC725Y data key is the hash of the `tokenId` and `dataKey` concatenated - -
- -**Emitted events:** - -- [`TokenIdDataChanged`](#tokeniddatachanged) event. - -
- -#### Parameters - -| Name | Type | Description | -| ----------- | :-------: | ---------------------------------------- | -| `tokenId` | `bytes32` | The unique identifier for a token. | -| `dataKey` | `bytes32` | The key for the data to set. | -| `dataValue` | `bytes` | The value to set for the given data key. | - -
- -### \_getDataForTokenId - -```solidity -function _getDataForTokenId( - bytes32 tokenId, - bytes32 dataKey -) internal view returns (bytes dataValues); -``` - -Retrieves data for a specific `tokenId` and `dataKey` from the ERC725Y storage -The ERC725Y data key is the hash of the `tokenId` and `dataKey` concatenated - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ---------------------------------- | -| `tokenId` | `bytes32` | The unique identifier for a token. | -| `dataKey` | `bytes32` | The key for the data to retrieve. | - -#### Returns - -| Name | Type | Description | -| ------------ | :-----: | ----------------------------------------------------------------- | -| `dataValues` | `bytes` | The data value associated with the given `tokenId` and `dataKey`. | - -
- -### \_beforeTokenTransfer - -```solidity -function _beforeTokenTransfer( - address from, - address to, - bytes32 tokenId, - bytes data -) internal nonpayable; -``` - -Hook that is called before any token transfer, including minting and burning. -Allows to run custom logic before updating balances and notifiying sender/recipient by overriding this function. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | -------------------------------------- | -| `from` | `address` | The sender address | -| `to` | `address` | @param tokenId The tokenId to transfer | -| `tokenId` | `bytes32` | The tokenId to transfer | -| `data` | `bytes` | The data sent alongside the transfer | - -
- -### \_afterTokenTransfer - -```solidity -function _afterTokenTransfer( - address from, - address to, - bytes32 tokenId, - bytes data -) internal nonpayable; -``` - -Hook that is called after any token transfer, including minting and burning. -Allows to run custom logic after updating balances, but **before notifiying sender/recipient via LSP1** by overriding this function. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | -------------------------------------- | -| `from` | `address` | The sender address | -| `to` | `address` | @param tokenId The tokenId to transfer | -| `tokenId` | `bytes32` | The tokenId to transfer | -| `data` | `bytes` | The data sent alongside the transfer | - -
- -### \_notifyTokenOperator - -```solidity -function _notifyTokenOperator( - address operator, - bytes lsp1Data -) internal nonpayable; -``` - -Attempt to notify the operator `operator` about the `tokenId` being authorized. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP8_TOKENOPERATOR` as typeId, if `operator` is a contract that supports the LSP1 interface. -If `operator` is an EOA or a contract that does not support the LSP1 interface, nothing will happen and no notification will be sent. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------------------------------------------------ | -| `operator` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `lsp1Data` | `bytes` | the data to be sent to the `operator` address in the `universalReceiver` call. | - -
- -### \_notifyTokenSender - -```solidity -function _notifyTokenSender(address from, bytes lsp1Data) internal nonpayable; -``` - -Attempt to notify the token sender `from` about the `tokenId` being transferred. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP8_TOKENSSENDER` as typeId, if `from` is a contract that supports the LSP1 interface. -If `from` is an EOA or a contract that does not support the LSP1 interface, nothing will happen and no notification will be sent. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ------------------------------------------------------------------------------ | -| `from` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `lsp1Data` | `bytes` | the data to be sent to the `from` address in the `universalReceiver` call. | - -
- -### \_notifyTokenReceiver - -```solidity -function _notifyTokenReceiver( - address to, - bool force, - bytes lsp1Data -) internal nonpayable; -``` - -Attempt to notify the token receiver `to` about the `tokenId` being received. -This is done by calling its [`universalReceiver`](#universalreceiver) function with the `_TYPEID_LSP8_TOKENSRECIPIENT` as typeId, if `to` is a contract that supports the LSP1 interface. -If `to` is is an EOA or a contract that does not support the LSP1 interface, the behaviour will depend on the `force` boolean flag. - -- if `force` is set to `true`, nothing will happen and no notification will be sent. - -- if `force` is set to `false, the transaction will revert. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | --------------------------------------------------------------------------------------------------- | -| `to` | `address` | The address to call the [`universalReceiver`](#universalreceiver) function on. | -| `force` | `bool` | A boolean that describe if transfer to a `to` address that does not support LSP1 is allowed or not. | -| `lsp1Data` | `bytes` | The data to be sent to the `to` address in the `universalReceiver(...)` call. | - -
- -### \_supportsInterfaceInERC165Extension - -```solidity -function _supportsInterfaceInERC165Extension( - bytes4 interfaceId -) internal view returns (bool); -``` - -Returns whether the interfaceId being checked is supported in the extension of the -[`supportsInterface`](#supportsinterface) selector. -To be used by extendable contracts wishing to extend the ERC165 interfaceIds originally -supported by reading whether the interfaceId queried is supported in the `supportsInterface` -extension if the extension is set, if not it returns false. - -
- -### \_getExtensionAndForwardValue - -```solidity -function _getExtensionAndForwardValue( - bytes4 functionSelector -) internal view returns (address, bool); -``` - -Returns the extension address stored under the following data key: - -- [`_LSP17_EXTENSION_PREFIX`](#_lsp17_extension_prefix) + `` (Check [LSP2-ERC725YJSONSchema] for encoding the data key). - -- If no extension is stored, returns the address(0). - -
- -### \_fallbackLSP17Extendable - -:::info - -The LSP8 Token contract should not hold any native tokens. Any native tokens received by the contract -will be forwarded to the extension address mapped to the selector from `msg.sig`. - -::: - -```solidity -function _fallbackLSP17Extendable( - bytes callData -) internal nonpayable returns (bytes); -``` - -Forwards the call with the received value to an extension mapped to a function selector. -Calls [`_getExtensionAndForwardValue`](#_getextensionandforwardvalue) to get the address of the extension mapped to the function selector being -called on the account. If there is no extension, the address(0) will be returned. -We will always forward the value to the extension, as the LSP8 contract is not supposed to hold any native tokens. -Reverts if there is no extension for the function being called. -If there is an extension for the function selector being called, it calls the extension with the -CALL opcode, passing the [`msg.data`](#msg.data) appended with the 20 bytes of the [`msg.sender`](#msg.sender) and -32 bytes of the [`msg.value`](#msg.value) - -
- -### \_safeTransfer - -```solidity -function _safeTransfer( - address from, - address to, - uint256 tokenId, - bytes data -) internal nonpayable; -``` - -Transfer the `tokenId` from `from` to `to` and check if the `to` recipient address is -a contract that implements the `IERC721Received` interface and return the right magic value. -See [`_checkOnERC721Received`](#_checkonerc721received) for more infos. - -
- -### \_setApprovalForAll - -```solidity -function _setApprovalForAll( - address tokensOwner, - address operator, - bool approved -) internal nonpayable; -``` - -Approve `operator` to operate on all tokens of `tokensOwner`. - -
- -**Emitted events:** - -- [`ApprovalForAll`](#approvalforall) event. - -
- -
- -## Events - -### Approval - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#approval) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Event signature: `Approval(address,address,uint256)` -- Event topic hash: `0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925` - -::: - -```solidity -event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); -``` - -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` | - | -| `approved` **`indexed`** | `address` | - | -| `tokenId` **`indexed`** | `uint256` | - | - -
- -### ApprovalForAll - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#approvalforall) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Event signature: `ApprovalForAll(address,address,bool)` -- Event topic hash: `0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31` - -::: - -```solidity -event ApprovalForAll(address indexed owner, address indexed operator, bool approved); -``` - -Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to `approved`. - -#### Parameters - -| Name | Type | Description | -| ------------------------ | :-------: | ----------- | -| `owner` **`indexed`** | `address` | - | -| `operator` **`indexed`** | `address` | - | -| `approved` | `bool` | - | - -
- -### DataChanged - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#datachanged) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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. | - -
- -### OperatorAuthorizationChanged - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#operatorauthorizationchanged) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Event signature: `OperatorAuthorizationChanged(address,address,bytes32,bytes)` -- Event topic hash: `0x1b1b58aa2ec0cec2228b2d37124556d41f5a1f7b12f089171f896cc236671215` - -::: - -```solidity -event OperatorAuthorizationChanged(address indexed operator, address indexed tokenOwner, bytes32 indexed tokenId, bytes operatorNotificationData); -``` - -Emitted when `tokenOwner` enables `operator` to transfer or burn the `tokenId`. - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | -------------------------------------------------------------------- | -| `operator` **`indexed`** | `address` | The address authorized as an operator. | -| `tokenOwner` **`indexed`** | `address` | The owner of the `tokenId`. | -| `tokenId` **`indexed`** | `bytes32` | The tokenId `operator` address has access on behalf of `tokenOwner`. | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### OperatorRevoked - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#operatorrevoked) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Event signature: `OperatorRevoked(address,address,bytes32,bool,bytes)` -- Event topic hash: `0xc78cd419d6136f9f1c1c6aec1d3fae098cffaf8bc86314a8f2685e32fe574e3c` - -::: - -```solidity -event OperatorRevoked(address indexed operator, address indexed tokenOwner, bytes32 indexed tokenId, bool notified, bytes operatorNotificationData); -``` - -Emitted when `tokenOwner` disables `operator` to transfer or burn `tokenId` on its behalf. - -#### Parameters - -| Name | Type | Description | -| -------------------------- | :-------: | ---------------------------------------------------------------------------------- | -| `operator` **`indexed`** | `address` | The address revoked from the operator array ([`getOperatorsOf`](#getoperatorsof)). | -| `tokenOwner` **`indexed`** | `address` | The owner of the `tokenId`. | -| `tokenId` **`indexed`** | `bytes32` | The tokenId `operator` is revoked from operating on. | -| `notified` | `bool` | Bool indicating whether the operator has been notified or not | -| `operatorNotificationData` | `bytes` | The data to notify the operator about via LSP1. | - -
- -### OwnershipTransferred - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#ownershiptransferred) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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` | - | - -
- -### TokenIdDataChanged - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#tokeniddatachanged) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Event signature: `TokenIdDataChanged(bytes32,bytes32,bytes)` -- Event topic hash: `0xa6e4251f855f750545fe414f120db91c76b88def14d120969e5bb2d3f05debbb` - -::: - -```solidity -event TokenIdDataChanged(bytes32 indexed tokenId, bytes32 indexed dataKey, bytes dataValue); -``` - -Emitted when setting data for `tokenId`. - -#### Parameters - -| Name | Type | Description | -| ----------------------- | :-------: | -------------------------------------------- | -| `tokenId` **`indexed`** | `bytes32` | The tokenId which data is set for. | -| `dataKey` **`indexed`** | `bytes32` | The data key for which a bytes value is set. | -| `dataValue` | `bytes` | The value to set for the given data key. | - -
- -### Transfer - -:::note References - -- 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` - -::: - -```solidity -event Transfer(address operator, address indexed from, address indexed to, bytes32 indexed tokenId, bool force, bytes data); -``` - -Emitted when `tokenId` token is transferred from the `from` to the `to` address. - -#### 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. | - -
- -### Transfer - -:::note References - -- 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` - -::: - -```solidity -event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); -``` - -Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero. - -#### Parameters - -| Name | Type | Description | -| ----------------------- | :-------: | ----------- | -| `from` **`indexed`** | `address` | - | -| `to` **`indexed`** | `address` | - | -| `tokenId` **`indexed`** | `uint256` | - | - -
- -## Errors - -### ERC725Y_DataKeysValuesEmptyArray - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#erc725y_datakeysvaluesemptyarray) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#erc725y_datakeysvalueslengthmismatch) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#erc725y_msgvaluedisallowed) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `ERC725Y_MsgValueDisallowed()` -- Error hash: `0xf36ba737` - -::: - -```solidity -error ERC725Y_MsgValueDisallowed(); -``` - -Reverts when sending value to the [`setData`](#setdata) or [`setDataBatch`](#setdatabatch) function. - -
- -### InvalidExtensionAddress - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#invalidextensionaddress) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `InvalidExtensionAddress(bytes)` -- Error hash: `0x42bfe79f` - -::: - -```solidity -error InvalidExtensionAddress(bytes storedData); -``` - -reverts when the bytes retrieved from the LSP17 data key is not a valid address (not 20 bytes) - -#### Parameters - -| Name | Type | Description | -| ------------ | :-----: | ----------- | -| `storedData` | `bytes` | - | - -
- -### InvalidFunctionSelector - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#invalidfunctionselector) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `InvalidFunctionSelector(bytes)` -- Error hash: `0xe5099ee3` - -::: - -```solidity -error InvalidFunctionSelector(bytes data); -``` - -reverts when the contract is called with a function selector not valid (less than 4 bytes of data) - -#### Parameters - -| Name | Type | Description | -| ------ | :-----: | ----------- | -| `data` | `bytes` | - | - -
- -### LSP4TokenNameNotEditable - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp4tokennamenoteditable) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP4TokenNameNotEditable()` -- Error hash: `0x85c169bd` - -::: - -```solidity -error LSP4TokenNameNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenName` after the digital asset contract has been deployed / initialized. The `LSP4TokenName` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor/initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP4TokenSymbolNotEditable - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp4tokensymbolnoteditable) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP4TokenSymbolNotEditable()` -- Error hash: `0x76755b38` - -::: - -```solidity -error LSP4TokenSymbolNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenSymbol` after the digital asset contract has been deployed / initialized. The `LSP4TokenSymbol` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor/initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP4TokenTypeNotEditable - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp4tokentypenoteditable) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP4TokenTypeNotEditable()` -- Error hash: `0x4ef6d7fb` - -::: - -```solidity -error LSP4TokenTypeNotEditable(); -``` - -Reverts when trying to edit the data key `LSP4TokenType` after the digital asset contract has been deployed / initialized. The `LSP4TokenType` data key is located inside the ERC725Y data key-value store of the digital asset contract. It can be set only once inside the constructor / initializer when the digital asset contract is being deployed / initialized. - -
- -### LSP8BatchCallFailed - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8batchcallfailed) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8BatchCallFailed(uint256)` -- Error hash: `0x234eb819` - -::: - -```solidity -error LSP8BatchCallFailed(uint256 callIndex); -``` - -_Batch call failed._ - -Reverts when a batch call failed. - -#### Parameters - -| Name | Type | Description | -| ----------- | :-------: | ----------- | -| `callIndex` | `uint256` | - | - -
- -### LSP8CannotSendToAddressZero - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotsendtoaddresszero) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8CannotSendToAddressZero()` -- Error hash: `0x24ecef4d` - -::: - -```solidity -error LSP8CannotSendToAddressZero(); -``` - -Reverts when trying to send token to the zero address. - -
- -### LSP8CannotSendToSelf - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotsendtoself) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8CannotSendToSelf()` -- Error hash: `0x5d67d6c1` - -::: - -```solidity -error LSP8CannotSendToSelf(); -``` - -Reverts when specifying the same address for `from` and `to` in a token transfer. - -
- -### LSP8CannotUseAddressZeroAsOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8cannotuseaddresszeroasoperator) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8CannotUseAddressZeroAsOperator()` -- Error hash: `0x9577b8b3` - -::: - -```solidity -error LSP8CannotUseAddressZeroAsOperator(); -``` - -Reverts when trying to set the zero address as an operator. - -
- -### LSP8InvalidTransferBatch - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8invalidtransferbatch) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8InvalidTransferBatch()` -- Error hash: `0x93a83119` - -::: - -```solidity -error LSP8InvalidTransferBatch(); -``` - -Reverts when the parameters used for `transferBatch` have different lengths. - -
- -### LSP8NonExistentTokenId - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8nonexistenttokenid) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8NonExistentTokenId(bytes32)` -- Error hash: `0xae8f9a36` - -::: - -```solidity -error LSP8NonExistentTokenId(bytes32 tokenId); -``` - -Reverts when `tokenId` has not been minted. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ----------- | -| `tokenId` | `bytes32` | - | - -
- -### LSP8NonExistingOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8nonexistingoperator) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8NonExistingOperator(address,bytes32)` -- Error hash: `0x4aa31a8c` - -::: - -```solidity -error LSP8NonExistingOperator(address operator, bytes32 tokenId); -``` - -Reverts when `operator` is not an operator for the `tokenId`. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `operator` | `address` | - | -| `tokenId` | `bytes32` | - | - -
- -### LSP8NotTokenOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8nottokenoperator) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8NotTokenOperator(bytes32,address)` -- Error hash: `0x1294d2a9` - -::: - -```solidity -error LSP8NotTokenOperator(bytes32 tokenId, address caller); -``` - -Reverts when `caller` is not an allowed operator for `tokenId`. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ----------- | -| `tokenId` | `bytes32` | - | -| `caller` | `address` | - | - -
- -### LSP8NotTokenOwner - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8nottokenowner) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8NotTokenOwner(address,bytes32,address)` -- Error hash: `0x5b271ea2` - -::: - -```solidity -error LSP8NotTokenOwner(address tokenOwner, bytes32 tokenId, address caller); -``` - -Reverts when `caller` is not the `tokenOwner` of the `tokenId`. - -#### Parameters - -| Name | Type | Description | -| ------------ | :-------: | ----------- | -| `tokenOwner` | `address` | - | -| `tokenId` | `bytes32` | - | -| `caller` | `address` | - | - -
- -### LSP8NotifyTokenReceiverContractMissingLSP1Interface - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8notifytokenreceivercontractmissinglsp1interface) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8NotifyTokenReceiverContractMissingLSP1Interface(address)` -- Error hash: `0x4349776d` - -::: - -```solidity -error LSP8NotifyTokenReceiverContractMissingLSP1Interface( - address tokenReceiver -); -``` - -Reverts if the `tokenReceiver` does not implement LSP1 when minting or transferring tokens with `bool force` set as `false`. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ----------- | -| `tokenReceiver` | `address` | - | - -
- -### LSP8NotifyTokenReceiverIsEOA - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8notifytokenreceiveriseoa) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8NotifyTokenReceiverIsEOA(address)` -- Error hash: `0x03173137` - -::: - -```solidity -error LSP8NotifyTokenReceiverIsEOA(address tokenReceiver); -``` - -Reverts if the `tokenReceiver` is an EOA when minting or transferring tokens with `bool force` set as `false`. - -#### Parameters - -| Name | Type | Description | -| --------------- | :-------: | ----------- | -| `tokenReceiver` | `address` | - | - -
- -### LSP8OperatorAlreadyAuthorized - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8operatoralreadyauthorized) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8OperatorAlreadyAuthorized(address,bytes32)` -- Error hash: `0xa7626b68` - -::: - -```solidity -error LSP8OperatorAlreadyAuthorized(address operator, bytes32 tokenId); -``` - -Reverts when `operator` is already authorized for the `tokenId`. - -#### Parameters - -| Name | Type | Description | -| ---------- | :-------: | ----------- | -| `operator` | `address` | - | -| `tokenId` | `bytes32` | - | - -
- -### LSP8TokenContractCannotHoldValue - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokencontractcannotholdvalue) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8TokenContractCannotHoldValue()` -- Error hash: `0x61f49442` - -::: - -```solidity -error LSP8TokenContractCannotHoldValue(); -``` - -_LSP8 contract cannot receive native tokens._ - -Error occurs when sending native tokens to the LSP8 contract without sending any data. E.g. Sending value without passing a bytes4 function selector to call a LSP17 Extension. - -
- -### LSP8TokenIdAlreadyMinted - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenidalreadyminted) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8TokenIdAlreadyMinted(bytes32)` -- Error hash: `0x34c7b511` - -::: - -```solidity -error LSP8TokenIdAlreadyMinted(bytes32 tokenId); -``` - -Reverts when `tokenId` has already been minted. - -#### Parameters - -| Name | Type | Description | -| --------- | :-------: | ----------- | -| `tokenId` | `bytes32` | - | - -
- -### LSP8TokenIdFormatNotEditable - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenidformatnoteditable) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8TokenIdFormatNotEditable()` -- Error hash: `0x3664800a` - -::: - -```solidity -error LSP8TokenIdFormatNotEditable(); -``` - -Reverts when trying to edit the data key `LSP8TokenIdFormat` after the identifiable digital asset contract has been deployed. The `LSP8TokenIdFormat` data key is located inside the ERC725Y Data key-value store of the identifiable digital asset contract. It can be set only once inside the constructor/initializer when the identifiable digital asset contract is being deployed. - -
- -### LSP8TokenIdsDataEmptyArray - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenidsdataemptyarray) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8TokenIdsDataEmptyArray()` -- Error hash: `0x80c98305` - -::: - -```solidity -error LSP8TokenIdsDataEmptyArray(); -``` - -Reverts when empty arrays is passed to the function - -
- -### LSP8TokenIdsDataLengthMismatch - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenidsdatalengthmismatch) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8TokenIdsDataLengthMismatch()` -- Error hash: `0x2fa71dfe` - -::: - -```solidity -error LSP8TokenIdsDataLengthMismatch(); -``` - -Reverts when the length of the token IDs data arrays is not equal - -
- -### LSP8TokenOwnerCannotBeOperator - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenownercannotbeoperator) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `LSP8TokenOwnerCannotBeOperator()` -- Error hash: `0x89fdad62` - -::: - -```solidity -error LSP8TokenOwnerCannotBeOperator(); -``` - -Reverts when trying to authorize or revoke the token's owner as an operator. - -
- -### NoExtensionFoundForFunctionSelector - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#noextensionfoundforfunctionselector) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol) -- Error signature: `NoExtensionFoundForFunctionSelector(bytes4)` -- Error hash: `0xbb370b2b` - -::: - -```solidity -error NoExtensionFoundForFunctionSelector(bytes4 functionSelector); -``` - -reverts when there is no extension for the function selector being called with - -#### Parameters - -| Name | Type | Description | -| ------------------ | :------: | ----------- | -| `functionSelector` | `bytes4` | - | - -
- -### OwnableCallerNotTheOwner - -:::note References - -- Specification details: [**LSP-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#ownablecallernottheowner) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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-8-IdentifiableDigitalAsset**](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#ownablecannotsetzeroaddressasowner) -- Solidity implementation: [`LSP8CompatibleERC721Mintable.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.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/dodoc/config.ts b/dodoc/config.ts index 3f0610a40..65662a652 100644 --- a/dodoc/config.ts +++ b/dodoc/config.ts @@ -27,15 +27,11 @@ export const dodocConfig = { 'contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol', 'contracts/LSP7DigitalAsset/extensions/LSP7Burnable.sol', 'contracts/LSP7DigitalAsset/extensions/LSP7CappedSupply.sol', - 'contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol', - 'contracts/LSP7DigitalAsset/presets/LSP7CompatibleERC20Mintable.sol', 'contracts/LSP7DigitalAsset/presets/LSP7Mintable.sol', 'contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol', 'contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Burnable.sol', 'contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.sol', - 'contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol', 'contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8Enumerable.sol', - 'contracts/LSP8IdentifiableDigitalAsset/presets/LSP8CompatibleERC721Mintable.sol', 'contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.sol', // libraries -------------------- diff --git a/hardhat.config.ts b/hardhat.config.ts index fa0b73099..63ab5b9e4 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -149,16 +149,6 @@ const config: HardhatUserConfig = { 'LSP8MintableInit', 'LSP9VaultInit', 'LSP11BasicSocialRecoveryInit', - // ERC Compatible tokens - // ------------------ - 'LSP7CompatibleERC20', - 'LSP7CompatibleERC20InitAbstract', - 'LSP7CompatibleERC20Mintable', - 'LSP7CompatibleERC20MintableInit', - 'LSP8CompatibleERC721', - 'LSP8CompatibleERC721InitAbstract', - 'LSP8CompatibleERC721Mintable', - 'LSP8CompatibleERC721MintableInit', // Legacy L14 // ------------------ 'UniversalReceiverAddressStore', diff --git a/tests/LSP7DigitalAsset/LSP7CompatibleERC20.behaviour.ts b/tests/LSP7DigitalAsset/LSP7CompatibleERC20.behaviour.ts deleted file mode 100644 index 1f9df0e9d..000000000 --- a/tests/LSP7DigitalAsset/LSP7CompatibleERC20.behaviour.ts +++ /dev/null @@ -1,1330 +0,0 @@ -import { ethers } from 'hardhat'; -import { expect } from 'chai'; - -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -import { BigNumber, ContractTransaction } from 'ethers'; -import type { TransactionResponse } from '@ethersproject/abstract-provider'; - -import { INTERFACE_IDS, SupportedStandards } from '../../constants'; -import { - CheckInterface__factory, - LSP7CompatibleERC20, - LSP7CompatibleERC20Tester, - TokenReceiverWithLSP1, - TokenReceiverWithLSP1__factory, - TokenReceiverWithoutLSP1, - TokenReceiverWithoutLSP1__factory, - UniversalReceiverDelegateRevert, - UniversalReceiverDelegateRevert__factory, -} from '../../types'; -import { ERC725YDataKeys } from '../../constants'; -import { abiCoder } from '../utils/helpers'; - -type LSP7CompatibleERC20TestAccounts = { - owner: SignerWithAddress; - tokenReceiver: SignerWithAddress; - operator: SignerWithAddress; - anotherOperator: SignerWithAddress; - anyone: SignerWithAddress; -}; - -export const getNamedAccounts = async (): Promise => { - const [owner, tokenReceiver, operator, anotherOperator, anyone] = await ethers.getSigners(); - return { owner, tokenReceiver, operator, anotherOperator, anyone }; -}; - -export type LSP7CompatibleERC20DeployParams = { - name: string; - symbol: string; - newOwner: string; - lsp4TokenType: number; -}; - -export type LSP7CompatibleERC20TestContext = { - accounts: LSP7CompatibleERC20TestAccounts; - lsp7CompatibleERC20: LSP7CompatibleERC20Tester; - deployParams: LSP7CompatibleERC20DeployParams; - initialSupply: BigNumber; -}; - -export type ExpectedError = { - error: string; - args: string[]; -}; - -export const shouldBehaveLikeLSP7CompatibleERC20 = ( - buildContext: () => Promise, -) => { - let context: LSP7CompatibleERC20TestContext; - - beforeEach(async () => { - context = await buildContext(); - }); - - describe('approve', () => { - describe('when operator is the zero address', () => { - it('should revert', async () => { - await expect( - context.lsp7CompatibleERC20.approve(ethers.constants.AddressZero, context.initialSupply), - ).to.be.revertedWithCustomError( - context.lsp7CompatibleERC20, - 'LSP7CannotUseAddressZeroAsOperator', - ); - }); - }); - - describe('when the operator had no authorized amount', () => { - it('should succeed by setting the given amount', async () => { - const operator = context.accounts.operator.address; - const tokenOwner = context.accounts.owner.address; - const authorizedAmount = 1; - - const preAllowance = await context.lsp7CompatibleERC20.allowance(tokenOwner, operator); - expect(preAllowance).to.equal(0); - - const tx = await context.lsp7CompatibleERC20.approve(operator, authorizedAmount); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'OperatorAuthorizationChanged') - .withArgs(operator, tokenOwner, authorizedAmount, '0x'); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'Approval') - .withArgs(tokenOwner, operator, authorizedAmount); - - const postAllowance = await context.lsp7CompatibleERC20.allowance(tokenOwner, operator); - expect(postAllowance).to.equal(authorizedAmount); - }); - - describe('approving an LSP1 contract', () => { - it('should succeed and inform the operator', async () => { - const tokenReceiverWithLSP1: TokenReceiverWithLSP1 = - await new TokenReceiverWithLSP1__factory(context.accounts.owner).deploy(); - const operator = tokenReceiverWithLSP1.address; - const tokenOwner = context.accounts.owner.address; - const amount = 1; - - const tx = await context.lsp7CompatibleERC20.approve(operator, amount, { - gasLimit: 2000000, - }); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'OperatorAuthorizationChanged') - .withArgs(operator, tokenOwner, amount, '0x'); - - await expect(tx).to.emit(tokenReceiverWithLSP1, 'UniversalReceiver'); - - expect( - await context.lsp7CompatibleERC20.authorizedAmountFor(operator, tokenOwner), - ).to.equal(amount); - }); - - it('should succeed and inform the operator even if the operator revert', async () => { - const operatorThatReverts: UniversalReceiverDelegateRevert = - await new UniversalReceiverDelegateRevert__factory(context.accounts.owner).deploy(); - const operator = operatorThatReverts.address; - const tokenOwner = context.accounts.owner.address; - const amount = 1; - - const tx = await context.lsp7CompatibleERC20.approve(operator, amount); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'OperatorAuthorizationChanged') - .withArgs(operator, tokenOwner, amount, '0x'); - - expect( - await context.lsp7CompatibleERC20.authorizedAmountFor(operator, tokenOwner), - ).to.equal(amount); - }); - }); - }); - - describe('when the operator had an authorized amount', () => { - describe('when the operator authorized amount is changed to another non-zero value', () => { - it('should succeed by replacing the existing amount with the given amount', async () => { - const operator = context.accounts.operator.address; - const tokenOwner = context.accounts.owner.address; - const previouslyAuthorizedAmount = '20'; - const authorizedAmount = '1'; - - await context.lsp7CompatibleERC20.approve(operator, previouslyAuthorizedAmount); - - const preAllowance = await context.lsp7CompatibleERC20.allowance(tokenOwner, operator); - expect(preAllowance).to.equal(previouslyAuthorizedAmount); - - const tx = await context.lsp7CompatibleERC20.approve(operator, authorizedAmount); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'OperatorAuthorizationChanged') - .withArgs(operator, tokenOwner, authorizedAmount, '0x'); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'Approval') - .withArgs(tokenOwner, operator, authorizedAmount); - - const postAllowance = await context.lsp7CompatibleERC20.allowance(tokenOwner, operator); - expect(postAllowance).to.equal(authorizedAmount); - }); - }); - - describe('when the operator authorized amount is changed to zero', () => { - it('should succeed by replacing the existing amount with the given amount', async () => { - const operator = context.accounts.operator.address; - const tokenOwner = context.accounts.owner.address; - const previouslyAuthorizedAmount = '20'; - const authorizedAmount = '0'; - - await context.lsp7CompatibleERC20.approve(operator, previouslyAuthorizedAmount); - - const preAllowance = await context.lsp7CompatibleERC20.allowance(tokenOwner, operator); - expect(preAllowance).to.equal(previouslyAuthorizedAmount); - - const tx = await context.lsp7CompatibleERC20.approve(operator, authorizedAmount); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'OperatorRevoked') - .withArgs(operator, tokenOwner, false, '0x'); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'Approval') - .withArgs(tokenOwner, operator, authorizedAmount); - - const postAllowance = await context.lsp7CompatibleERC20.allowance(tokenOwner, operator); - expect(postAllowance).to.equal(authorizedAmount); - }); - - describe('changing the allowance of an LSP1 contract to zero', () => { - it('should succeed and not inform the operator', async () => { - const tokenReceiverWithLSP1: TokenReceiverWithLSP1 = - await new TokenReceiverWithLSP1__factory(context.accounts.owner).deploy(); - const operator = tokenReceiverWithLSP1.address; - const tokenOwner = context.accounts.owner.address; - - const tx = await context.lsp7CompatibleERC20.approve(operator, 0, { - gasLimit: 2000000, - }); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'OperatorRevoked') - .withArgs(operator, tokenOwner, false, '0x'); - - expect(tx).to.not.emit(tokenReceiverWithLSP1, 'UniversalReceiver'); - - expect( - await context.lsp7CompatibleERC20.authorizedAmountFor(operator, tokenOwner), - ).to.equal(ethers.constants.Zero); - }); - - it('should succeed and inform the operator even if the operator revert', async () => { - const operatorThatReverts: UniversalReceiverDelegateRevert = - await new UniversalReceiverDelegateRevert__factory(context.accounts.owner).deploy(); - const operator = operatorThatReverts.address; - const tokenOwner = context.accounts.owner.address; - - const tx = await context.lsp7CompatibleERC20.approve(operator, 0); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'OperatorRevoked') - .withArgs(operator, tokenOwner, false, '0x'); - - expect( - await context.lsp7CompatibleERC20.authorizedAmountFor(operator, tokenOwner), - ).to.equal(ethers.constants.Zero); - }); - }); - }); - }); - }); - - describe('allowance', () => { - describe('when operator has been approved', () => { - it('should return approval amount', async () => { - await context.lsp7CompatibleERC20.approve( - context.accounts.operator.address, - context.initialSupply, - ); - - expect( - await context.lsp7CompatibleERC20.allowance( - context.accounts.owner.address, - context.accounts.operator.address, - ), - ).to.equal(context.initialSupply); - }); - }); - - describe('when operator has not been approved', () => { - it('should return zero', async () => { - expect( - await context.lsp7CompatibleERC20.allowance( - context.accounts.owner.address, - context.accounts.anyone.address, - ), - ).to.equal(ethers.constants.Zero); - }); - }); - }); - - describe('mint', () => { - describe('when a token is minted', () => { - it('should have expected events', async () => { - const txParams = { - to: context.accounts.owner.address, - amount: context.initialSupply, - data: ethers.utils.toUtf8Bytes('mint tokens for the owner'), - }; - const operator = context.accounts.owner; - - const tx = await context.lsp7CompatibleERC20 - .connect(operator) - .mint(txParams.to, txParams.amount, txParams.data); - - await expect(tx) - .to.emit( - context.lsp7CompatibleERC20, - 'Transfer(address,address,address,uint256,bool,bytes)', - ) - .withArgs( - operator.address, - ethers.constants.AddressZero, - txParams.to, - txParams.amount, - true, - ethers.utils.hexlify(txParams.data), - ); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'Transfer(address,address,uint256)') - .withArgs(ethers.constants.AddressZero, txParams.to, txParams.amount); - }); - }); - }); - - describe('burn', () => { - describe('when a token is burned', () => { - beforeEach(async () => { - await context.lsp7CompatibleERC20.mint( - context.accounts.owner.address, - context.initialSupply, - ethers.utils.toUtf8Bytes('mint tokens for owner'), - ); - }); - - it('should have expected events', async () => { - const txParams = { - from: context.accounts.owner.address, - amount: context.initialSupply, - data: ethers.utils.toUtf8Bytes('burn tokens from the owner'), - }; - const operator = context.accounts.owner; - - const tx = await context.lsp7CompatibleERC20 - .connect(operator) - .burn(txParams.from, txParams.amount, txParams.data); - - await expect(tx) - .to.emit( - context.lsp7CompatibleERC20, - 'Transfer(address,address,address,uint256,bool,bytes)', - ) - .withArgs( - operator.address, - txParams.from, - ethers.constants.AddressZero, - txParams.amount, - false, - ethers.utils.hexlify(txParams.data), - ); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'Transfer(address,address,uint256)') - .withArgs(txParams.from, ethers.constants.AddressZero, txParams.amount); - }); - }); - }); - - describe('transfers', () => { - type TestDeployedContracts = { - tokenReceiverWithLSP1: TokenReceiverWithLSP1; - tokenReceiverWithoutLSP1: TokenReceiverWithoutLSP1; - }; - let deployedContracts: TestDeployedContracts; - - beforeEach(async () => { - deployedContracts = { - tokenReceiverWithLSP1: await new TokenReceiverWithLSP1__factory( - context.accounts.owner, - ).deploy(), - tokenReceiverWithoutLSP1: await new TokenReceiverWithoutLSP1__factory( - context.accounts.owner, - ).deploy(), - }; - }); - - beforeEach(async () => { - // setup so we have tokens to transfer - await context.lsp7CompatibleERC20.mint( - context.accounts.owner.address, - context.initialSupply, - ethers.utils.toUtf8Bytes('mint tokens for the owner'), - ); - - // setup so we can observe allowance values during transfer tests - await context.lsp7CompatibleERC20.approve( - context.accounts.operator.address, - context.initialSupply, - ); - }); - - type TransferParams = { - // we make the operator of type SignerWithAddress because it is used to sign the transaction - // when calling the contract via `contractName.connect(operator).functionName(...)` - operator: SignerWithAddress; - from: string; - to: string; - amount: BigNumber; - force?: boolean; - data?: string; - }; - - const transferSuccessScenario = async ( - txParams: TransferParams, - sendTransaction: () => Promise, - expectedData: string, - ) => { - // pre-conditions - const preBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - const preAllowance = await context.lsp7CompatibleERC20.allowance( - txParams.from, - txParams.operator.address, - ); - - // effect - const tx = await sendTransaction(); - await expect(tx) - .to.emit( - context.lsp7CompatibleERC20, - 'Transfer(address,address,address,uint256,bool,bytes)', - ) - .withArgs( - txParams.operator.address, - txParams.from, - txParams.to, - txParams.amount, - txParams.force ?? true, - expectedData, - ); - - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'Transfer(address,address,uint256)') - .withArgs(txParams.from, txParams.to, txParams.amount); - - // post-conditions - const postBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - expect(postBalanceOf).to.equal(preBalanceOf.sub(txParams.amount)); - - if (txParams.operator.address !== txParams.from) { - const postAllowance = await context.lsp7CompatibleERC20.allowance( - txParams.from, - txParams.operator.address, - ); - expect(postAllowance).to.equal(preAllowance.sub(txParams.amount)); - - // check for ERC20 Approval event - await expect(tx) - .to.emit(context.lsp7CompatibleERC20, 'Approval(address,address,uint256)') - .withArgs(txParams.from, txParams.operator.address, postAllowance); - } - - // if the recipient is a contract that implements LSP1, - // CHECK that it emitted the UniversalReceiver event on the receiver end. - const erc165Checker = await new CheckInterface__factory(context.accounts.owner).deploy(); - - const isLSP1Recipient = await erc165Checker.supportsERC165InterfaceUnchecked( - txParams.to, - INTERFACE_IDS.LSP1UniversalReceiver, - ); - - if (isLSP1Recipient) { - const receiver = await new TokenReceiverWithLSP1__factory(context.accounts.owner).attach( - txParams.to, - ); - - await expect(tx).to.emit(receiver, 'UniversalReceiver'); - } - }; - - describe('ERC20 -> `transfer(address,uint256)`', () => { - describe('when sender has enough balance', () => { - const transferAmount = ethers.BigNumber.from('10'); - - describe('when `to` is an EOA', () => { - it('should allow transfering the tokens', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: context.accounts.tokenReceiver.address, - amount: transferAmount, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,uint256)'](txParams.to, txParams.amount), - '0x', - ); - }); - }); - - describe('when `to` is a contract', () => { - describe('when receiving contract supports LSP1', () => { - it('should allow transfering the tokens', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1.address, - amount: transferAmount, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,uint256)'](txParams.to, txParams.amount), - '0x', - ); - }); - }); - - describe('when receiving contract does not support LSP1', () => { - it('should allow transfering the tokens', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: transferAmount, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,uint256)'](txParams.to, txParams.amount), - '0x', - ); - }); - }); - }); - }); - - describe('when sender does not have enough balance', () => { - it("should revert with `LSP7AmountExceedsBalance` error if sending more tokens than the tokenOwner's balance", async () => { - const ownerBalance = await context.lsp7CompatibleERC20.balanceOf( - context.accounts.owner.address, - ); - - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: ownerBalance.add(1), - }; - - // pre-conditions - const preBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - - await expect( - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.amount, - ), - ) - .to.be.revertedWithCustomError(context.lsp7CompatibleERC20, 'LSP7AmountExceedsBalance') - .withArgs(ownerBalance.toHexString(), txParams.from, txParams.amount.toHexString()); - - // post-conditions - const postBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - expect(postBalanceOf).to.equal(preBalanceOf); - }); - }); - }); - - describe('ERC20 -> `transferFrom(address,address,uint256)`', () => { - describe('when sender has enough balance', () => { - const transferAmount = ethers.BigNumber.from('10'); - - describe('when caller (msg.sender) is the `from` address', () => { - describe('when `to` is an EOA', () => { - it('should allow transfering the tokens', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: context.accounts.tokenReceiver.address, - amount: transferAmount, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - .transferFrom(txParams.from, txParams.to, txParams.amount), - '0x', - ); - }); - }); - - describe('when `to` is a contract', () => { - describe('when receiving contract supports LSP1', () => { - it('should allow transfering the tokens', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1.address, - amount: transferAmount, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - .transferFrom(txParams.from, txParams.to, txParams.amount), - '0x', - ); - }); - }); - - describe('when receiving contract does not support LSP1', () => { - it('should allow transfering the tokens', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: transferAmount, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - .transferFrom(txParams.from, txParams.to, txParams.amount), - '0x', - ); - }); - }); - }); - }); - - describe('when caller (msg.sender) is an operator (= Not the `from` address)', () => { - describe('when `to` is an EOA', () => { - it('should allow transfering the tokens', async () => { - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: context.accounts.tokenReceiver.address, - amount: transferAmount, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - .transferFrom(txParams.from, txParams.to, txParams.amount), - '0x', - ); - }); - }); - - describe('when `to` is a contract', () => { - describe('when receiving contract supports LSP1', () => { - it('should allow transfering the tokens', async () => { - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1.address, - amount: transferAmount, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - .transferFrom(txParams.from, txParams.to, txParams.amount), - '0x', - ); - }); - }); - - describe('when receiving contract does not support LSP1', () => { - it('should allow transfering the tokens', async () => { - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: transferAmount, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - .transferFrom(txParams.from, txParams.to, txParams.amount), - '0x', - ); - }); - }); - }); - }); - }); - - describe('when sender does not have enough balance', () => { - describe('when caller (msg.sender) is the `from` address', () => { - it("should revert with `LSP7AmountExceedsBalance` error if sending more tokens than the tokenOwner's balance", async () => { - const ownerBalance = await context.lsp7CompatibleERC20.balanceOf( - context.accounts.owner.address, - ); - - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: ownerBalance.add(1), - }; - - // pre-conditions - const preBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - - await expect( - context.lsp7CompatibleERC20 - .connect(txParams.operator) - .transferFrom(txParams.from, txParams.to, txParams.amount), - ) - .to.be.revertedWithCustomError( - context.lsp7CompatibleERC20, - 'LSP7AmountExceedsBalance', - ) - .withArgs(ownerBalance.toHexString(), txParams.from, txParams.amount.toHexString()); - - // post-conditions - const postBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - expect(postBalanceOf).to.equal(preBalanceOf); - }); - }); - - describe('when caller (msg.sender) is an operator (= Not the `from` address)', () => { - it("should revert with `LSP7AmountExceedsAuthorizedAmount` error if sending more tokens than the tokenOwner's balance", async () => { - const ownerBalance = await context.lsp7CompatibleERC20.balanceOf( - context.accounts.owner.address, - ); - - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: ownerBalance.add(1), - }; - - // pre-conditions - const preBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - - await expect( - context.lsp7CompatibleERC20 - .connect(txParams.operator) - .transferFrom(txParams.from, txParams.to, txParams.amount), - ) - .to.be.revertedWithCustomError( - context.lsp7CompatibleERC20, - 'LSP7AmountExceedsAuthorizedAmount', - ) - .withArgs( - context.accounts.owner.address, - ownerBalance.toHexString(), - txParams.operator.address, - txParams.amount.toHexString(), - ); - - // post-conditions - const postBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - expect(postBalanceOf).to.equal(preBalanceOf); - }); - }); - }); - }); - - describe('LSP7 -> `transfer(address,address,uint256,bool,bytes)`', () => { - const expectedData = ethers.utils.hexlify(ethers.utils.toUtf8Bytes('LSP7 token transfer')); - - describe('when sender has enough balance', () => { - const transferAmount = ethers.BigNumber.from('10'); - - describe('when caller (msg.sender) is the `from` address', () => { - describe('when `to` is an EOA', () => { - it('should allow transfering the tokens with `force` param = true', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: context.accounts.tokenReceiver.address, - amount: transferAmount, - force: true, - data: expectedData, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - expectedData, - ); - }); - - it('should NOT allow transfering the tokens with `force` param = false', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: context.accounts.tokenReceiver.address, - amount: transferAmount, - force: false, - data: expectedData, - }; - - // pre-conditions - const preBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - - await expect( - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - ) - .to.be.revertedWithCustomError( - context.lsp7CompatibleERC20, - 'LSP7NotifyTokenReceiverIsEOA', - ) - .withArgs(txParams.to); - - // post-conditions - const postBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - expect(postBalanceOf).to.equal(preBalanceOf); - }); - }); - - describe('when `to` is a contract', () => { - describe('when receiving contract supports LSP1', () => { - it('should allow transfering the tokens with `force` param = true', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1.address, - amount: transferAmount, - force: true, - data: expectedData, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - expectedData, - ); - }); - - it('should allow transfering the tokens with `force` param = false', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1.address, - amount: transferAmount, - force: false, - data: expectedData, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - expectedData, - ); - }); - }); - - describe('when receiving contract does not support LSP1', () => { - it('should allow transfering the tokens with `force` param = true', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: transferAmount, - force: true, - data: expectedData, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - expectedData, - ); - }); - - it('should NOT allow transfering the tokens with `force` param = false', async () => { - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: transferAmount, - force: false, - data: expectedData, - }; - - // pre-conditions - const preBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - - await expect( - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - ) - .to.be.revertedWithCustomError( - context.lsp7CompatibleERC20, - 'LSP7NotifyTokenReceiverContractMissingLSP1Interface', - ) - .withArgs(txParams.to); - - // post-conditions - const postBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - expect(postBalanceOf).to.equal(preBalanceOf); - }); - }); - }); - }); - - describe('when caller (msg.sender) is an operator (= Not the `from` address)', () => { - describe('when `to` is an EOA', () => { - it('should allow transfering the tokens with `force` param = true', async () => { - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: context.accounts.tokenReceiver.address, - amount: transferAmount, - force: true, - data: expectedData, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - expectedData, - ); - }); - - it('should NOT allow transfering the tokens with `force` param = false', async () => { - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: context.accounts.tokenReceiver.address, - amount: transferAmount, - force: false, - data: expectedData, - }; - - // pre-conditions - const preBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - - await expect( - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - ) - .to.be.revertedWithCustomError( - context.lsp7CompatibleERC20, - 'LSP7NotifyTokenReceiverIsEOA', - ) - .withArgs(txParams.to); - - // post-conditions - const postBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - expect(postBalanceOf).to.equal(preBalanceOf); - }); - }); - - describe('when `to` is a contract', () => { - describe('when receiving contract supports LSP1', () => { - it('should allow transfering the tokens with `force` param = true', async () => { - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1.address, - amount: transferAmount, - force: true, - data: expectedData, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - expectedData, - ); - }); - - it('should allow transfering the tokens with `force` param = false', async () => { - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1.address, - amount: transferAmount, - force: false, - data: expectedData, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - expectedData, - ); - }); - }); - - describe('when receiving contract does not support LSP1', () => { - it('should allow transfering the tokens with `force` param = true', async () => { - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: transferAmount, - force: true, - data: expectedData, - }; - - await transferSuccessScenario( - txParams, - () => - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - expectedData, - ); - }); - - it('should NOT allow transfering the tokens with `force` param = false', async () => { - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: transferAmount, - force: false, - data: expectedData, - }; - - // pre-conditions - const preBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - - await expect( - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - ) - .to.be.revertedWithCustomError( - context.lsp7CompatibleERC20, - 'LSP7NotifyTokenReceiverContractMissingLSP1Interface', - ) - .withArgs(txParams.to); - - // post-conditions - const postBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - expect(postBalanceOf).to.equal(preBalanceOf); - }); - }); - }); - }); - }); - - describe('when sender does not have enough balance', () => { - describe('when caller (msg.sender) is the `from` address', () => { - it("should revert with `LSP7AmountExceedsBalance` error if sending more tokens than the tokenOwner's balance", async () => { - const ownerBalance = await context.lsp7CompatibleERC20.balanceOf( - context.accounts.owner.address, - ); - - const txParams = { - operator: context.accounts.owner, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: ownerBalance.add(1), - force: true, - data: expectedData, - }; - - // pre-conditions - const preBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - - await expect( - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - ) - .to.be.revertedWithCustomError( - context.lsp7CompatibleERC20, - 'LSP7AmountExceedsBalance', - ) - .withArgs(ownerBalance.toHexString(), txParams.from, txParams.amount.toHexString()); - - // post-conditions - const postBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - expect(postBalanceOf).to.equal(preBalanceOf); - }); - }); - - describe('when caller (msg.sender) is an operator (= Not the `from` address)', () => { - it("should revert with `LSP7AmountExceedsAuthorizedAmount` error if sending more tokens than the tokenOwner's balance", async () => { - const ownerBalance = await context.lsp7CompatibleERC20.balanceOf( - context.accounts.owner.address, - ); - - const txParams = { - operator: context.accounts.operator, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - amount: ownerBalance.add(1), - force: true, - data: expectedData, - }; - - // pre-conditions - const preBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - - await expect( - context.lsp7CompatibleERC20 - .connect(txParams.operator) - ['transfer(address,address,uint256,bool,bytes)']( - txParams.from, - txParams.to, - txParams.amount, - txParams.force, - txParams.data, - ), - ) - .to.be.revertedWithCustomError( - context.lsp7CompatibleERC20, - 'LSP7AmountExceedsAuthorizedAmount', - ) - .withArgs( - context.accounts.owner.address, - ownerBalance.toHexString(), - txParams.operator.address, - txParams.amount.toHexString(), - ); - - // post-conditions - const postBalanceOf = await context.lsp7CompatibleERC20.balanceOf(txParams.from); - expect(postBalanceOf).to.equal(preBalanceOf); - }); - }); - }); - }); - }); -}; - -export type LSP7InitializeTestContext = { - lsp7CompatibleERC20: LSP7CompatibleERC20; - deployParams: LSP7CompatibleERC20DeployParams; - initializeTransaction: TransactionResponse; -}; - -export const shouldInitializeLikeLSP7CompatibleERC20 = ( - buildContext: () => Promise, -) => { - let context: LSP7InitializeTestContext; - - before(async () => { - context = await buildContext(); - }); - - describe('when the contract was initialized', () => { - 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 () => { - await expect(context.initializeTransaction) - .to.emit(context.lsp7CompatibleERC20, 'DataChanged') - .withArgs( - SupportedStandards.LSP4DigitalAsset.key, - SupportedStandards.LSP4DigitalAsset.value, - ); - expect( - await context.lsp7CompatibleERC20.getData(SupportedStandards.LSP4DigitalAsset.key), - ).to.equal(SupportedStandards.LSP4DigitalAsset.value); - - const nameKey = ERC725YDataKeys.LSP4.LSP4TokenName; - const expectedNameValue = ethers.utils.hexlify( - ethers.utils.toUtf8Bytes(context.deployParams.name), - ); - await expect(context.initializeTransaction) - .to.emit(context.lsp7CompatibleERC20, 'DataChanged') - .withArgs(nameKey, expectedNameValue); - expect(await context.lsp7CompatibleERC20.getData(nameKey)).to.equal(expectedNameValue); - - const symbolKey = ERC725YDataKeys.LSP4.LSP4TokenSymbol; - const expectedSymbolValue = ethers.utils.hexlify( - ethers.utils.toUtf8Bytes(context.deployParams.symbol), - ); - await expect(context.initializeTransaction) - .to.emit(context.lsp7CompatibleERC20, 'DataChanged') - .withArgs(symbolKey, expectedSymbolValue); - expect(await context.lsp7CompatibleERC20.getData(symbolKey)).to.equal(expectedSymbolValue); - - const tokenTypeKey = ERC725YDataKeys.LSP4['LSP4TokenType']; - const expectedTokenTypeValue = abiCoder.encode( - ['uint256'], - [context.deployParams.lsp4TokenType], - ); - expect(await context.lsp7CompatibleERC20.getData(tokenTypeKey)).to.equal( - expectedTokenTypeValue, - ); - }); - - 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/LSP7DigitalAsset/proxy/LSP7CompatibleERC20Init.test.ts b/tests/LSP7DigitalAsset/proxy/LSP7CompatibleERC20Init.test.ts deleted file mode 100644 index c98a47f2c..000000000 --- a/tests/LSP7DigitalAsset/proxy/LSP7CompatibleERC20Init.test.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { ethers } from 'hardhat'; -import { expect } from 'chai'; - -import { - LSP7CompatibleERC20InitTester__factory, - LSP7CompatibleERC20MintableInit__factory, -} from '../../../types'; - -import { - getNamedAccounts, - LSP7CompatibleERC20TestContext, - shouldInitializeLikeLSP7CompatibleERC20, - shouldBehaveLikeLSP7CompatibleERC20, -} from '../LSP7CompatibleERC20.behaviour'; - -import { deployProxy } from '../../utils/fixtures'; -import { LSP4_TOKEN_TYPES } from '../../../constants'; - -describe('LSP7CompatibleERC20Init with proxy', () => { - const buildTestContext = async (): Promise => { - const accounts = await getNamedAccounts(); - const initialSupply = ethers.BigNumber.from('1000'); - const deployParams = { - name: 'LSP7 - deployed with constructor', - symbol: 'NFT', - newOwner: accounts.owner.address, - lsp4TokenType: LSP4_TOKEN_TYPES.TOKEN, - }; - - const lsp7CompatibilityForERC20TesterInit = await new LSP7CompatibleERC20InitTester__factory( - accounts.owner, - ).deploy(); - const lsp7CompatibilityForERC20Proxy = await deployProxy( - lsp7CompatibilityForERC20TesterInit.address, - accounts.owner, - ); - const lsp7CompatibleERC20 = lsp7CompatibilityForERC20TesterInit.attach( - lsp7CompatibilityForERC20Proxy, - ); - - return { - accounts, - lsp7CompatibleERC20, - deployParams, - initialSupply, - }; - }; - - const initializeProxy = async (context: LSP7CompatibleERC20TestContext) => { - return context.lsp7CompatibleERC20['initialize(string,string,address,uint256)']( - context.deployParams.name, - context.deployParams.symbol, - context.deployParams.newOwner, - context.deployParams.lsp4TokenType, - ); - }; - - describe('when deploying the base implementation contract', () => { - it('LSP7CompatibleERC20Init: prevent any address from calling the initialize(...) function on the implementation', async () => { - const accounts = await ethers.getSigners(); - - const lsp7CompatibilityForERC20TesterInit = await new LSP7CompatibleERC20InitTester__factory( - accounts[0], - ).deploy(); - - const randomCaller = accounts[1]; - - await expect( - lsp7CompatibilityForERC20TesterInit['initialize(string,string,address,uint256)']( - 'XXXXXXXXXXX', - 'XXX', - randomCaller.address, - 12345, - ), - ).to.be.revertedWith('Initializable: contract is already initialized'); - }); - - it('LSP7CompatibleERC20MintableInit: prevent any address from calling the initialize(...) function on the implementation', async () => { - const accounts = await ethers.getSigners(); - - const lsp7CompatibleERC20MintableInit = await new LSP7CompatibleERC20MintableInit__factory( - accounts[0], - ).deploy(); - - const randomCaller = accounts[1]; - - await expect( - lsp7CompatibleERC20MintableInit['initialize(string,string,address,uint256)']( - 'XXXXXXXXXXX', - 'XXX', - randomCaller.address, - 12345, - ), - ).to.be.revertedWith('Initializable: contract is already initialized'); - }); - }); - - describe('when deploying the contract as proxy', () => { - let context: LSP7CompatibleERC20TestContext; - - before(async () => { - context = await buildTestContext(); - }); - - describe('when initializing the contract', () => { - shouldInitializeLikeLSP7CompatibleERC20(async () => { - const { lsp7CompatibleERC20, deployParams } = context; - const initializeTransaction = await initializeProxy(context); - - return { - lsp7CompatibleERC20, - deployParams, - initializeTransaction, - }; - }); - }); - - describe('when calling initialize more than once', () => { - it('should revert', async () => { - await expect(initializeProxy(context)).to.be.revertedWith( - 'Initializable: contract is already initialized', - ); - }); - }); - }); - - describe('when testing deployed contract', () => { - shouldBehaveLikeLSP7CompatibleERC20(() => - buildTestContext().then(async (context) => { - await initializeProxy(context); - - return context; - }), - ); - }); -}); diff --git a/tests/LSP7DigitalAsset/standard/LSP7CompatibleERC20.test.ts b/tests/LSP7DigitalAsset/standard/LSP7CompatibleERC20.test.ts deleted file mode 100644 index 0c37f48ea..000000000 --- a/tests/LSP7DigitalAsset/standard/LSP7CompatibleERC20.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { ethers } from 'hardhat'; - -import { LSP7CompatibleERC20Tester__factory } from '../../../types'; - -import { - getNamedAccounts, - LSP7CompatibleERC20TestContext, - shouldInitializeLikeLSP7CompatibleERC20, - shouldBehaveLikeLSP7CompatibleERC20, -} from '../LSP7CompatibleERC20.behaviour'; -import { LSP4_TOKEN_TYPES } from '../../../constants'; - -describe('LSP7CompatibleERC20 with constructor', () => { - const buildTestContext = async (): Promise => { - const accounts = await getNamedAccounts(); - const initialSupply = ethers.BigNumber.from('1000'); - const deployParams = { - name: 'Compat for ERC20', - symbol: 'NFT', - newOwner: accounts.owner.address, - lsp4TokenType: LSP4_TOKEN_TYPES.TOKEN, - }; - - const lsp7CompatibleERC20 = await new LSP7CompatibleERC20Tester__factory(accounts.owner).deploy( - deployParams.name, - deployParams.symbol, - deployParams.newOwner, - deployParams.lsp4TokenType, - ); - - return { - accounts, - lsp7CompatibleERC20, - deployParams, - initialSupply, - }; - }; - - describe('when deploying the contract', () => { - let context: LSP7CompatibleERC20TestContext; - - before(async () => { - context = await buildTestContext(); - }); - - describe('when initializing the contract', () => { - shouldInitializeLikeLSP7CompatibleERC20(async () => { - const { lsp7CompatibleERC20, deployParams } = context; - return { - lsp7CompatibleERC20, - deployParams, - initializeTransaction: context.lsp7CompatibleERC20.deployTransaction, - }; - }); - }); - }); - - describe('when testing deployed contract', () => { - shouldBehaveLikeLSP7CompatibleERC20(buildTestContext); - }); -}); diff --git a/tests/LSP8IdentifiableDigitalAsset/LSP8CompatibleERC721.behaviour.ts b/tests/LSP8IdentifiableDigitalAsset/LSP8CompatibleERC721.behaviour.ts deleted file mode 100644 index efe527a77..000000000 --- a/tests/LSP8IdentifiableDigitalAsset/LSP8CompatibleERC721.behaviour.ts +++ /dev/null @@ -1,1337 +0,0 @@ -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -import { ethers } from 'hardhat'; -import { expect } from 'chai'; - -import { - LSP8CompatibleERC721Tester, - TokenReceiverWithLSP1, - TokenReceiverWithLSP1__factory, - TokenReceiverWithoutLSP1__factory, - TokenReceiverWithoutLSP1, - TokenReceiverWithLSP1WithERC721ReceivedRevert, - TokenReceiverWithLSP1WithERC721ReceivedRevert__factory, - TokenReceiverWithLSP1WithERC721ReceivedInvalid, - TokenReceiverWithLSP1WithERC721ReceivedInvalid__factory, - TokenReceiverWithLSP1WithERC721Received, - TokenReceiverWithLSP1WithERC721Received__factory, - TokenReceiverWithoutLSP1WithERC721ReceivedRevert, - TokenReceiverWithoutLSP1WithERC721ReceivedRevert__factory, - TokenReceiverWithoutLSP1WithERC721ReceivedInvalid, - TokenReceiverWithoutLSP1WithERC721ReceivedInvalid__factory, - TokenReceiverWithoutLSP1WithERC721Received, - TokenReceiverWithoutLSP1WithERC721Received__factory, - UniversalReceiverDelegateRevert, - UniversalReceiverDelegateRevert__factory, -} from '../../types'; -import { tokenIdAsBytes32 } from '../utils/tokens'; -import { ERC725YDataKeys, INTERFACE_IDS, SupportedStandards } from '../../constants'; - -import type { BytesLike } from 'ethers'; -import type { TransactionResponse } from '@ethersproject/abstract-provider'; -import { abiCoder } from '../utils/helpers'; - -export type LSP8CompatibleERC721TestAccounts = { - owner: SignerWithAddress; - tokenReceiver: SignerWithAddress; - operator: SignerWithAddress; - anotherOperator: SignerWithAddress; - anyone: SignerWithAddress; -}; - -export const getNamedAccounts = async (): Promise => { - const [owner, tokenReceiver, operator, anotherOperator, anyone] = await ethers.getSigners(); - return { owner, tokenReceiver, operator, anotherOperator, anyone }; -}; - -type LSP8CompatibleERC721DeployParams = { - name: string; - symbol: string; - newOwner: string; - lsp4TokenType: number; - lsp8TokenIdFormat: number; - lsp4MetadataValue: string; -}; - -export type LSP8CompatibleERC721TestContext = { - accounts: LSP8CompatibleERC721TestAccounts; - lsp8CompatibleERC721: LSP8CompatibleERC721Tester; - deployParams: LSP8CompatibleERC721DeployParams; -}; - -export type ExpectedError = { - error: string; - args: string[]; -}; - -const mintedTokenId = '10'; -const neverMintedTokenId = '1010110'; - -export const shouldBehaveLikeLSP8CompatibleERC721 = ( - buildContext: () => Promise, -) => { - let context: LSP8CompatibleERC721TestContext; - - beforeEach(async () => { - context = await buildContext(); - }); - - describe('when setting data', () => { - it('should not allow to update the `lsp8TokenIdFormat` after deployment', async () => { - await expect( - context.lsp8CompatibleERC721.setData(ERC725YDataKeys.LSP8.LSP8TokenIdFormat, '0xdeadbeef'), - ).to.be.revertedWithCustomError(context.lsp8CompatibleERC721, 'LSP8TokenIdFormatNotEditable'); - }); - }); - - describe('when setting data', () => { - it('should not allow to update the `lsp8TokenIdFormat` after deployment', async () => { - await expect( - context.lsp8CompatibleERC721.setData(ERC725YDataKeys.LSP8.LSP8TokenIdFormat, '0xdeadbeef'), - ).to.be.revertedWithCustomError(context.lsp8CompatibleERC721, 'LSP8TokenIdFormatNotEditable'); - }); - }); - - describe('when checking supported ERC165 interfaces', () => { - it('should support ERC721', async () => { - expect(await context.lsp8CompatibleERC721.supportsInterface(INTERFACE_IDS.ERC721)).to.equal( - true, - ); - }); - - it('should support ERC721Metadata', async () => { - expect( - await context.lsp8CompatibleERC721.supportsInterface(INTERFACE_IDS.ERC721Metadata), - ).to.equal(true); - }); - }); - - describe('name', () => { - 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(bytes32)']( - ethers.utils.keccak256(ethers.utils.toUtf8Bytes('LSP4TokenName')), - ); - expect(ethers.utils.toUtf8String(nameAsBytes)).to.equal(context.deployParams.name); - }); - }); - - describe('symbol', () => { - 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(bytes32)']( - ethers.utils.keccak256(ethers.utils.toUtf8Bytes('LSP4TokenSymbol')), - ); - expect(ethers.utils.toUtf8String(symbolAsBytes)).to.equal(context.deployParams.symbol); - }); - }); - - describe('tokenURI', () => { - it('should allow reading tokenURI', async () => { - // using compatibility getter -> returns(string) - const tokenURIAsString = await context.lsp8CompatibleERC721.tokenURI(mintedTokenId); - // offset = bytes4(hashSig) + bytes32(contentHash) -> 4 + 32 = 36 + 2 for prefix = 38 - const offset = 36 * 2 + 2; - expect(tokenURIAsString).to.equal( - ethers.utils.toUtf8String(`0x${context.deployParams.lsp4MetadataValue.slice(offset)}`), - ); - - // using getData -> returns(bytes) - const lsp4MetadataValueAsBytes = await context.lsp8CompatibleERC721['getData(bytes32)']( - ethers.utils.keccak256(ethers.utils.toUtf8Bytes('LSP4Metadata')), - ); - expect(lsp4MetadataValueAsBytes).to.equal(context.deployParams.lsp4MetadataValue); - }); - }); - - describe('ownerOf', () => { - describe('when tokenId has not been minted', () => { - it('should revert', async () => { - await expect(context.lsp8CompatibleERC721.ownerOf(neverMintedTokenId)) - .to.be.revertedWithCustomError(context.lsp8CompatibleERC721, 'LSP8NonExistentTokenId') - .withArgs(tokenIdAsBytes32(neverMintedTokenId)); - }); - }); - - describe('when tokenId has been minted', () => { - it('should return owner address', async () => { - await context.lsp8CompatibleERC721.mint( - context.accounts.owner.address, - mintedTokenId, - ethers.utils.toUtf8Bytes('mint a token for the owner'), - ); - - expect(await context.lsp8CompatibleERC721.ownerOf(mintedTokenId)).to.equal( - context.accounts.owner.address, - ); - }); - }); - }); - - describe('approve', () => { - describe('when tokenId has not been minted', () => { - it('should revert', async () => { - await expect( - context.lsp8CompatibleERC721 - .connect(context.accounts.anyone) - .approve(context.accounts.operator.address, neverMintedTokenId), - ) - .to.be.revertedWithCustomError(context.lsp8CompatibleERC721, 'LSP8NonExistentTokenId') - .withArgs(tokenIdAsBytes32(neverMintedTokenId)); - }); - }); - - describe('when the tokenId has been minted', () => { - beforeEach(async () => { - await context.lsp8CompatibleERC721.mint( - context.accounts.owner.address, - mintedTokenId, - ethers.utils.toUtf8Bytes('mint a token for the owner'), - ); - }); - - describe('when caller is not owner of tokenId', () => { - it('should revert', async () => { - await expect( - context.lsp8CompatibleERC721 - .connect(context.accounts.anyone) - .approve(context.accounts.operator.address, mintedTokenId), - ) - .to.be.revertedWithCustomError(context.lsp8CompatibleERC721, 'LSP8NotTokenOwner') - .withArgs( - context.accounts.owner.address, - tokenIdAsBytes32(mintedTokenId), - context.accounts.anyone.address, - ); - }); - }); - - describe('when caller is owner of tokenId', () => { - describe('when operator is not the zero address', () => { - it('should succeed', async () => { - const operator = context.accounts.operator.address; - const tokenId = mintedTokenId; - - const tx = await context.lsp8CompatibleERC721.approve(operator, tokenId); - - await expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'OperatorAuthorizationChanged') - .withArgs(operator, context.accounts.owner.address, tokenIdAsBytes32(tokenId), '0x'); - - await expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'Approval') - .withArgs(context.accounts.owner.address, operator, ethers.BigNumber.from(tokenId)); - }); - - describe('when approving an LSP1 contract', () => { - it('should succeed and inform the operator', async () => { - const tokenReceiverWithLSP1: TokenReceiverWithLSP1 = - await new TokenReceiverWithLSP1__factory(context.accounts.owner).deploy(); - const operator = tokenReceiverWithLSP1.address; - const tokenOwner = context.accounts.owner.address; - const tokenId = mintedTokenId; - - const tx = await context.lsp8CompatibleERC721.approve(operator, tokenId, { - gasLimit: 2000000, - }); - - await expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'OperatorAuthorizationChanged') - .withArgs(operator, tokenOwner, tokenIdAsBytes32(tokenId), '0x'); - - await expect(tx).to.emit(tokenReceiverWithLSP1, 'UniversalReceiver'); - - expect( - await context.lsp8CompatibleERC721.isOperatorFor( - operator, - tokenIdAsBytes32(tokenId), - ), - ).to.be.true; - }); - - it('should succeed and inform the operator even if the operator revert', async () => { - const operatorThatReverts: UniversalReceiverDelegateRevert = - await new UniversalReceiverDelegateRevert__factory(context.accounts.owner).deploy(); - const operator = operatorThatReverts.address; - const tokenOwner = context.accounts.owner.address; - const tokenId = mintedTokenId; - - const tx = await context.lsp8CompatibleERC721.approve(operator, tokenId); - - await expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'OperatorAuthorizationChanged') - .withArgs(operator, tokenOwner, tokenIdAsBytes32(tokenId), '0x'); - - expect( - await context.lsp8CompatibleERC721.isOperatorFor( - operator, - tokenIdAsBytes32(tokenId), - ), - ).to.be.true; - }); - }); - }); - - describe('when operator is the zero address', () => { - it('should revert', async () => { - const operator = ethers.constants.AddressZero; - const tokenId = mintedTokenId; - - await expect( - context.lsp8CompatibleERC721.approve(operator, tokenId), - ).to.be.revertedWithCustomError( - context.lsp8CompatibleERC721, - 'LSP8CannotUseAddressZeroAsOperator', - ); - }); - }); - }); - }); - }); - - describe('setApprovalForAll', () => { - const tokenIds = [ - ethers.utils.keccak256(ethers.utils.toUtf8Bytes('NFT 1')), - ethers.utils.keccak256(ethers.utils.toUtf8Bytes('NFT 2')), - ethers.utils.keccak256(ethers.utils.toUtf8Bytes('NFT 3')), - ethers.utils.keccak256(ethers.utils.toUtf8Bytes('NFT 4')), - ethers.utils.keccak256(ethers.utils.toUtf8Bytes('NFT 5')), - ]; - - beforeEach(async () => { - tokenIds.map(async (tokenId) => { - const txParams = { - to: context.accounts.owner.address, - tokenId: tokenId, - data: ethers.utils.toUtf8Bytes(`mint tokenId ${tokenId} for the owner`), - }; - - await context.lsp8CompatibleERC721 - .connect(context.accounts.owner) - .mint(txParams.to, txParams.tokenId, txParams.data); - }); - - await context.lsp8CompatibleERC721 - .connect(context.accounts.owner) - .setApprovalForAll(context.accounts.operator.address, true); - }); - - it('should be able to set approval for operator', async () => { - const tx = await context.lsp8CompatibleERC721 - .connect(context.accounts.operator) - .approve(context.accounts.anyone.address, tokenIds[0]); - - await expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'Approval') - .withArgs(context.accounts.owner.address, context.accounts.anyone.address, tokenIds[0]); - }); - - describe('when calling setApprovalForAll with true', () => { - it('should revert when trying to pass caller address as operator', async () => { - await expect( - context.lsp8CompatibleERC721 - .connect(context.accounts.owner) - .setApprovalForAll(context.accounts.owner.address, true), - ).to.be.revertedWith('LSP8CompatibleERC721: approve to caller'); - }); - - it('should have emitted an ApprovalForAll event', async () => { - const txParams = { - to: context.accounts.owner.address, - tokenId: 5, - data: ethers.utils.toUtf8Bytes(`mint tokenId 5 for the owner`), - }; - - await context.lsp8CompatibleERC721 - .connect(context.accounts.owner) - .mint(txParams.to, txParams.tokenId, txParams.data); - - const tx = await context.lsp8CompatibleERC721 - .connect(context.accounts.owner) - .setApprovalForAll(context.accounts.operator.address, true); - - expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'ApprovalForAll') - .withArgs(context.accounts.owner.address, context.accounts.operator.address, true); - }); - - describe('when calling isApprovedForAll', () => { - it('should return true for operator', async () => { - const result = await context.lsp8CompatibleERC721.isApprovedForAll( - context.accounts.owner.address, - context.accounts.operator.address, - ); - - expect(result).to.be.true; - }); - - it('should return false for non-operator', async () => { - const result = await context.lsp8CompatibleERC721.isApprovedForAll( - context.accounts.owner.address, - context.accounts.anyone.address, - ); - - expect(result).to.be.false; - }); - }); - }); - - describe('when operator transfer tokenId', () => { - [ - { tokenId: tokenIds[0] }, - { tokenId: tokenIds[1] }, - { tokenId: tokenIds[2] }, - { tokenId: tokenIds[3] }, - { tokenId: tokenIds[4] }, - ].forEach((testCase) => { - describe(`for tokenId ${testCase.tokenId}:`, () => { - it('should have transferred successfully with `transferFrom(...)` (changed token owner)', async () => { - const sender = context.accounts.owner.address; - const recipient = context.accounts.tokenReceiver.address; - - await context.lsp8CompatibleERC721 - .connect(context.accounts.operator) - .transferFrom(sender, recipient, testCase.tokenId); - - const newTokenOwner = await context.lsp8CompatibleERC721.ownerOf(testCase.tokenId); - expect(newTokenOwner).to.equal(context.accounts.tokenReceiver.address); - }); - - it('should have emitted a Transfer event', async () => { - const sender = context.accounts.owner.address; - const recipient = context.accounts.tokenReceiver.address; - - const tx = await context.lsp8CompatibleERC721 - .connect(context.accounts.operator) - .transferFrom(sender, recipient, testCase.tokenId); - - expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'Transfer(address,address,uint256)') - .withArgs(sender, recipient, testCase.tokenId); - }); - - it('should have cleared operators array', async () => { - // add 3 x individual operators per tokenId to test if the operators array is cleared - // once the tokenId has been transferred by operator that is approvedForAll - // const operatorsPerTokenIds = getRandomAddresses(1); - const operatorsPerTokenIdsBefore = [ - '0xcafecafecafecafecafecafecafecafecafecafe', - '0xbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef', - '0xf00df00df00df00df00df00df00df00df00df00d', - ]; - - await context.lsp8CompatibleERC721 - .connect(context.accounts.owner) - .approve(operatorsPerTokenIdsBefore[0], testCase.tokenId); - - await context.lsp8CompatibleERC721 - .connect(context.accounts.owner) - .approve(operatorsPerTokenIdsBefore[1], testCase.tokenId); - - await context.lsp8CompatibleERC721 - .connect(context.accounts.owner) - .approve(operatorsPerTokenIdsBefore[2], testCase.tokenId); - - const sender = context.accounts.owner.address; - const recipient = context.accounts.tokenReceiver.address; - - await context.lsp8CompatibleERC721 - .connect(context.accounts.operator) - .transferFrom(sender, recipient, testCase.tokenId); - - const operatorsForTokenIdAfter = await context.lsp8CompatibleERC721.getOperatorsOf( - testCase.tokenId, - ); - - expect(operatorsForTokenIdAfter).to.deep.equal([]); - }); - }); - }); - }); - - describe('when calling setApprovalForAll with false (removing operator full approval)', () => { - beforeEach(async () => { - await context.lsp8CompatibleERC721 - .connect(context.accounts.owner) - .setApprovalForAll(context.accounts.operator.address, false); - }); - - [ - { tokenId: tokenIds[0] }, - { tokenId: tokenIds[1] }, - { tokenId: tokenIds[2] }, - { tokenId: tokenIds[3] }, - { tokenId: tokenIds[4] }, - ].forEach((testCase) => { - it('should return false when calling isApprovedForAll for operator', async () => { - const result = await context.lsp8CompatibleERC721.isApprovedForAll( - context.accounts.owner.address, - context.accounts.operator.address, - ); - - expect(result).to.be.false; - }); - - it(`should revert when operator try to transfer tokenId ${testCase.tokenId} with transferFrom(...)`, async () => { - const tokenIdAsBytes32 = ethers.utils.hexZeroPad( - ethers.utils.hexValue(ethers.BigNumber.from(testCase.tokenId)), - 32, - ); - - await expect( - context.lsp8CompatibleERC721 - .connect(context.accounts.operator) - .transferFrom( - context.accounts.owner.address, - context.accounts.tokenReceiver.address, - testCase.tokenId, - ), - ) - .to.be.revertedWithCustomError(context.lsp8CompatibleERC721, 'LSP8NotTokenOperator') - .withArgs(tokenIdAsBytes32, context.accounts.operator.address); - }); - }); - }); - }); - - describe('getApproved', () => { - describe('when tokenId has not been minted', () => { - it('should revert', async () => { - await expect(context.lsp8CompatibleERC721.getApproved(neverMintedTokenId)) - .to.be.revertedWithCustomError(context.lsp8CompatibleERC721, 'LSP8NonExistentTokenId') - .withArgs(tokenIdAsBytes32(neverMintedTokenId)); - }); - }); - - describe('when tokenId has been minted', () => { - beforeEach(async () => { - await context.lsp8CompatibleERC721.mint( - context.accounts.owner.address, - mintedTokenId, - ethers.utils.toUtf8Bytes('mint a token for the owner'), - ); - }); - - describe('when there have been no approvals for the tokenId', () => { - it('should return address(0)', async () => { - expect(await context.lsp8CompatibleERC721.getApproved(mintedTokenId)).to.equal( - ethers.constants.AddressZero, - ); - }); - }); - - describe('when one account has been approved for the tokenId', () => { - it('should return the operator address', async () => { - await context.lsp8CompatibleERC721.approve( - context.accounts.operator.address, - tokenIdAsBytes32(mintedTokenId), - ); - - expect(await context.lsp8CompatibleERC721.getApproved(mintedTokenId)).to.equal( - context.accounts.operator.address, - ); - }); - }); - - describe('when many context.accounts have been approved for the tokenId', () => { - it('should return the last new authorized operator', async () => { - const operatorFirstAndThirdCall = context.accounts.operator.address; - const operatorSecondCall = context.accounts.anotherOperator.address; - - await context.lsp8CompatibleERC721.approve( - operatorFirstAndThirdCall, - tokenIdAsBytes32(mintedTokenId), - ); - await context.lsp8CompatibleERC721.approve( - operatorSecondCall, - tokenIdAsBytes32(mintedTokenId), - ); - - expect(await context.lsp8CompatibleERC721.getApproved(mintedTokenId)).to.equal( - context.accounts.anotherOperator.address, - ); - }); - }); - }); - }); - - describe('mint', () => { - describe('when a token is minted', () => { - it('should have expected events', async () => { - const txParams = { - to: context.accounts.owner.address, - tokenId: mintedTokenId, - data: ethers.utils.toUtf8Bytes('mint a token for the owner'), - }; - const operator = context.accounts.owner; - - const tx = await context.lsp8CompatibleERC721 - .connect(operator) - .mint(txParams.to, txParams.tokenId, txParams.data); - - await expect(tx) - .to.emit( - context.lsp8CompatibleERC721, - 'Transfer(address,address,address,bytes32,bool,bytes)', - ) - .withArgs( - operator.address, - ethers.constants.AddressZero, - txParams.to, - tokenIdAsBytes32(txParams.tokenId), - true, - ethers.utils.hexlify(txParams.data), - ); - - await expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'Transfer(address,address,uint256)') - .withArgs( - ethers.constants.AddressZero, - txParams.to, - ethers.BigNumber.from(txParams.tokenId), - ); - }); - }); - }); - - describe('burn', () => { - describe('when a token is burned', () => { - beforeEach(async () => { - await context.lsp8CompatibleERC721.mint( - context.accounts.owner.address, - mintedTokenId, - ethers.utils.toUtf8Bytes('mint a token for the owner'), - ); - }); - - it('should have expected events', async () => { - const txParams = { - tokenId: mintedTokenId, - data: ethers.utils.toUtf8Bytes('burn a token from the owner'), - }; - const operator = context.accounts.owner; - - const tx = await context.lsp8CompatibleERC721 - .connect(operator) - .burn(txParams.tokenId, txParams.data); - - await expect(tx) - .to.emit( - context.lsp8CompatibleERC721, - 'Transfer(address,address,address,bytes32,bool,bytes)', - ) - .withArgs( - operator.address, - operator.address, - ethers.constants.AddressZero, - tokenIdAsBytes32(txParams.tokenId), - false, - ethers.utils.hexlify(txParams.data), - ); - await expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'Transfer(address,address,uint256)') - .withArgs( - operator.address, - ethers.constants.AddressZero, - ethers.BigNumber.from(txParams.tokenId), - ); - }); - }); - }); - - describe('transfers', () => { - type TestDeployedContracts = { - tokenReceiverWithLSP1: TokenReceiverWithLSP1; - tokenReceiverWithoutLSP1: TokenReceiverWithoutLSP1; - tokenReceiverWithLSP1WithoutERC721Receiver: TokenReceiverWithLSP1; - tokenReceiverWithLSP1WithERC721ReceivedRevert: TokenReceiverWithLSP1WithERC721ReceivedRevert; - tokenReceiverWithLSP1WithERC721ReceivedInvalid: TokenReceiverWithLSP1WithERC721ReceivedInvalid; - tokenReceiverWithLSP1WithERC721Received: TokenReceiverWithLSP1WithERC721Received; - tokenReceiverWithoutLSP1WithoutERC721Received: TokenReceiverWithoutLSP1; - tokenReceiverWithoutLSP1WithERC721ReceivedRevert: TokenReceiverWithoutLSP1WithERC721ReceivedRevert; - tokenReceiverWithoutLSP1WithERC721ReceivedInvalid: TokenReceiverWithoutLSP1WithERC721ReceivedInvalid; - tokenReceiverWithoutLSP1WithERC721Received: TokenReceiverWithoutLSP1WithERC721Received; - }; - let deployedContracts: TestDeployedContracts; - - beforeEach(async () => { - // for `transfer` and `transferFrom` scenarios - deployedContracts = { - tokenReceiverWithLSP1: await new TokenReceiverWithLSP1__factory( - context.accounts.owner, - ).deploy(), - tokenReceiverWithoutLSP1: await new TokenReceiverWithoutLSP1__factory( - context.accounts.owner, - ).deploy(), - // for `safeTransferFrom` scenarios - tokenReceiverWithLSP1WithoutERC721Receiver: await new TokenReceiverWithLSP1__factory( - context.accounts.owner, - ).deploy(), - tokenReceiverWithLSP1WithERC721ReceivedRevert: - await new TokenReceiverWithLSP1WithERC721ReceivedRevert__factory( - context.accounts.owner, - ).deploy(), - tokenReceiverWithLSP1WithERC721ReceivedInvalid: - await new TokenReceiverWithLSP1WithERC721ReceivedInvalid__factory( - context.accounts.owner, - ).deploy(), - tokenReceiverWithLSP1WithERC721Received: - await new TokenReceiverWithLSP1WithERC721Received__factory( - context.accounts.owner, - ).deploy(), - tokenReceiverWithoutLSP1WithoutERC721Received: await new TokenReceiverWithoutLSP1__factory( - context.accounts.owner, - ).deploy(), - tokenReceiverWithoutLSP1WithERC721ReceivedRevert: - await new TokenReceiverWithoutLSP1WithERC721ReceivedRevert__factory( - context.accounts.owner, - ).deploy(), - tokenReceiverWithoutLSP1WithERC721ReceivedInvalid: - await new TokenReceiverWithoutLSP1WithERC721ReceivedInvalid__factory( - context.accounts.owner, - ).deploy(), - tokenReceiverWithoutLSP1WithERC721Received: - await new TokenReceiverWithoutLSP1WithERC721Received__factory( - context.accounts.owner, - ).deploy(), - }; - - // setup so we have a token to transfer - await context.lsp8CompatibleERC721.mint( - context.accounts.owner.address, - mintedTokenId, - ethers.utils.toUtf8Bytes('mint a token for the owner'), - ); - - // setup so we can observe approvals being cleared during transfer tests - await context.lsp8CompatibleERC721.approve(context.accounts.operator.address, mintedTokenId); - }); - - type TransferTxParams = { - operator: string; - from: string; - to: string; - tokenId: BytesLike; - data?: BytesLike; - }; - - const transferSuccessScenario = async ( - { operator, from, to, tokenId, data }: TransferTxParams, - transferFn: string, - force: boolean, - expectedData: string, - ) => { - // pre-conditions - const preOwnerOf = await context.lsp8CompatibleERC721.ownerOf(tokenId); - expect(preOwnerOf).to.equal(from); - - // effect - const txArgs = [from, to, tokenId]; - if (data) txArgs.push(data); - - const tx = await context.lsp8CompatibleERC721[transferFn](...txArgs); - - await expect(tx) - .to.emit( - context.lsp8CompatibleERC721, - 'Transfer(address,address,address,bytes32,bool,bytes)', - ) - .withArgs(operator, from, to, tokenIdAsBytes32(tokenId), force, expectedData); - - await expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'Transfer(address,address,uint256)') - .withArgs(from, to, ethers.BigNumber.from(tokenId)); - - await expect(tx) - .to.emit(context.lsp8CompatibleERC721, 'OperatorRevoked') - .withArgs(context.accounts.operator.address, from, tokenIdAsBytes32(tokenId), false, '0x'); - - // post-conditions - const postOwnerOf = await context.lsp8CompatibleERC721.ownerOf(tokenId); - expect(postOwnerOf).to.equal(to); - }; - - describe('transferFrom', () => { - const transferFn = 'transferFrom'; - const force = true; - const expectedData = ethers.utils.hexlify(ethers.utils.toUtf8Bytes('')); - - describe('when the from address is the tokenId owner', () => { - describe('when `to` is an EOA', () => { - it('should allow transfering the tokenId', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: context.accounts.tokenReceiver.address, - tokenId: mintedTokenId, - }; - - await transferSuccessScenario(txParams, transferFn, force, expectedData); - }); - }); - - describe('when `to` is a contract', () => { - describe('when receiving contract supports LSP1', () => { - it('should allow transfering the tokenId', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1.address, - tokenId: mintedTokenId, - }; - - await transferSuccessScenario(txParams, transferFn, force, expectedData); - }); - }); - - describe('when receiving contract does not support LSP1', () => { - it('should allow transfering the tokenId', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - tokenId: mintedTokenId, - }; - - await transferSuccessScenario(txParams, transferFn, force, expectedData); - }); - }); - }); - }); - - describe('when the from address is not the tokenId owner', () => { - it('should revert', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.anyone.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - tokenId: mintedTokenId, - }; - - // pre-conditions - const preOwnerOf = await context.lsp8CompatibleERC721.ownerOf(txParams.tokenId); - - await expect( - context.lsp8CompatibleERC721[transferFn](txParams.from, txParams.to, txParams.tokenId), - ) - .to.be.revertedWithCustomError(context.lsp8CompatibleERC721, 'LSP8NotTokenOwner') - .withArgs( - context.accounts.owner.address, - tokenIdAsBytes32(txParams.tokenId).toString(), - txParams.from, - ); - - // post-conditions - const postOwnerOf = await context.lsp8CompatibleERC721.ownerOf(txParams.tokenId); - expect(postOwnerOf).to.equal(preOwnerOf); - }); - }); - }); - - describe('safeTransferFrom(address,address,uint256)', () => { - const transferFn = 'safeTransferFrom(address,address,uint256)'; - - describe('when the from address is the tokenId owner', () => { - describe('when `to` is an EOA', () => { - it('should pass', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: context.accounts.tokenReceiver.address, - tokenId: mintedTokenId, - }; - - await transferSuccessScenario(txParams, transferFn, true, '0x'); - }); - }); - - describe('when `to` is a contract', () => { - describe('when the receiving contract supports LSP1', () => { - describe('when the receiving contract does not implement `onERC721Received`', () => { - it('should fail and revert', async () => { - const txParams = { - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1WithoutERC721Receiver.address, - tokenId: mintedTokenId, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.reverted; - }); - }); - - describe('when the receiving contract implements `onERC721Received`', () => { - it('should fail if the `onERC721Received` function reverts + bubble up the error', async () => { - const txParams = { - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1WithERC721ReceivedRevert.address, - tokenId: mintedTokenId, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.revertedWith( - 'TokenReceiverWithLSP1WithERC721ReceivedRevert: transfer rejected', - ); - }); - - it('should fail and revert if the `onERC721Received` function does not returns the correct bytes4 magic value', async () => { - const txParams = { - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1WithERC721ReceivedInvalid.address, - tokenId: mintedTokenId, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.revertedWith( - 'LSP8CompatibleERC721: transfer to non ERC721Receiver implementer', - ); - }); - - it('should pass if the `onERC721Received` function returns the correct bytes4 magic value', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1WithERC721Received.address, - tokenId: mintedTokenId, - }; - - await transferSuccessScenario(txParams, transferFn, true, '0x'); - }); - }); - }); - - describe('when the receiving contract does not support LSP1', () => { - describe('when the receiving contract does not implement `onERC721Received`', () => { - it('should fail and revert', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1WithoutERC721Received.address, - tokenId: mintedTokenId, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.reverted; - }); - }); - - describe('when the receiving contract implements `onERC721Received`', () => { - it('should fail if the `onERC721Received` function reverts + bubble up the error', async () => { - const txParams = { - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1WithERC721ReceivedRevert.address, - tokenId: mintedTokenId, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.revertedWith( - 'TokenReceiverWithLSP1WithERC721ReceivedRevert: transfer rejected', - ); - }); - - it('should fail and revert if the `onERC721Received` function does not returns the correct bytes4 magic value', async () => { - const txParams = { - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1WithERC721ReceivedInvalid.address, - tokenId: mintedTokenId, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.revertedWith( - 'LSP8CompatibleERC721: transfer to non ERC721Receiver implementer', - ); - }); - - it('should pass if the `onERC721Received` function returns the correct bytes4 magic value', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1WithERC721Received.address, - tokenId: mintedTokenId, - }; - - await transferSuccessScenario(txParams, transferFn, true, '0x'); - }); - }); - }); - }); - }); - - describe('when the from address is not the tokenId owner', () => { - it('should revert', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.anyone.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - tokenId: mintedTokenId, - }; - - // pre-conditions - const preOwnerOf = await context.lsp8CompatibleERC721.ownerOf(txParams.tokenId); - - await expect( - context.lsp8CompatibleERC721[transferFn](txParams.from, txParams.to, txParams.tokenId), - ) - .to.be.revertedWithCustomError(context.lsp8CompatibleERC721, 'LSP8NotTokenOwner') - .withArgs( - context.accounts.owner.address, - tokenIdAsBytes32(txParams.tokenId).toString(), - txParams.from, - ); - - // post-conditions - const postOwnerOf = await context.lsp8CompatibleERC721.ownerOf(txParams.tokenId); - expect(postOwnerOf).to.equal(preOwnerOf); - }); - }); - }); - - describe('safeTransferFrom(address,address,uint256,bytes)', () => { - const transferFn = 'safeTransferFrom(address,address,uint256,bytes)'; - const expectedData = ethers.utils.hexlify( - ethers.utils.toUtf8Bytes(`custom-data-${Date.now()}`), - ); - - describe('when the from address is the tokenId owner', () => { - describe('when `to` is an EOA', () => { - it('should pass', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: context.accounts.tokenReceiver.address, - tokenId: mintedTokenId, - data: expectedData, - }; - - await transferSuccessScenario(txParams, transferFn, true, expectedData); - }); - }); - - describe('when `to` is a contract', () => { - describe('when the receiving contract supports LSP1', () => { - describe('when the receiving contract does not implement `onERC721Received`', () => { - it('should fail and revert', async () => { - const txParams = { - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1WithoutERC721Receiver.address, - tokenId: mintedTokenId, - data: expectedData, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.reverted; - }); - }); - - describe('when the receiving contract implements `onERC721Received`', () => { - it('should fail if the `onERC721Received` function reverts + bubble up the error', async () => { - const txParams = { - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1WithERC721ReceivedRevert.address, - tokenId: mintedTokenId, - data: expectedData, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.revertedWith( - 'TokenReceiverWithLSP1WithERC721ReceivedRevert: transfer rejected', - ); - }); - - it('should fail and revert if the `onERC721Received` function does not returns the correct bytes4 magic value', async () => { - const txParams = { - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1WithERC721ReceivedInvalid.address, - tokenId: mintedTokenId, - data: expectedData, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.revertedWith( - 'LSP8CompatibleERC721: transfer to non ERC721Receiver implementer', - ); - }); - - it('should pass if the `onERC721Received` function returns the correct bytes4 magic value', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithLSP1WithERC721Received.address, - tokenId: mintedTokenId, - data: expectedData, - }; - - await transferSuccessScenario(txParams, transferFn, true, expectedData); - }); - }); - }); - - describe('when the receiving contract does not support LSP1', () => { - describe('when the receiving contract does not implement `onERC721Received`', () => { - it('should fail and revert', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1WithoutERC721Received.address, - tokenId: mintedTokenId, - data: expectedData, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.reverted; - }); - }); - - describe('when the receiving contract implements `onERC721Received`', () => { - it('should fail if the `onERC721Received` function reverts + bubble up the error', async () => { - const txParams = { - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1WithERC721ReceivedRevert.address, - tokenId: mintedTokenId, - data: expectedData, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.revertedWith( - 'TokenReceiverWithLSP1WithERC721ReceivedRevert: transfer rejected', - ); - }); - - it('should fail and revert if the `onERC721Received` function does not returns the correct bytes4 magic value', async () => { - const txParams = { - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1WithERC721ReceivedInvalid.address, - tokenId: mintedTokenId, - data: expectedData, - }; - - await expect( - context.lsp8CompatibleERC721['safeTransferFrom(address,address,uint256)']( - txParams.from, - txParams.to, - txParams.tokenId, - ), - ).to.be.revertedWith( - 'LSP8CompatibleERC721: transfer to non ERC721Receiver implementer', - ); - }); - - it('should pass if the `onERC721Received` function returns the correct bytes4 magic value', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.owner.address, - to: deployedContracts.tokenReceiverWithoutLSP1WithERC721Received.address, - tokenId: mintedTokenId, - data: expectedData, - }; - - await transferSuccessScenario(txParams, transferFn, true, expectedData); - }); - }); - }); - }); - }); - - describe('when the from address is not the tokenId owner', () => { - it('should revert', async () => { - const txParams = { - operator: context.accounts.owner.address, - from: context.accounts.anyone.address, - to: deployedContracts.tokenReceiverWithoutLSP1.address, - tokenId: mintedTokenId, - data: expectedData, - }; - - // pre-conditions - const preOwnerOf = await context.lsp8CompatibleERC721.ownerOf(txParams.tokenId); - - await expect( - context.lsp8CompatibleERC721[transferFn]( - txParams.from, - txParams.to, - txParams.tokenId, - txParams.data, - ), - ) - .to.be.revertedWithCustomError(context.lsp8CompatibleERC721, 'LSP8NotTokenOwner') - .withArgs( - context.accounts.owner.address, - tokenIdAsBytes32(txParams.tokenId).toString(), - txParams.from, - ); - - // post-conditions - const postOwnerOf = await context.lsp8CompatibleERC721.ownerOf(txParams.tokenId); - expect(postOwnerOf).to.equal(preOwnerOf); - }); - }); - }); - }); -}; - -export type LSP8InitializeTestContext = { - lsp8CompatibleERC721: LSP8CompatibleERC721Tester; - initializeTransaction: TransactionResponse; - deployParams: LSP8CompatibleERC721DeployParams; -}; - -export const shouldInitializeLikeLSP8CompatibleERC721 = ( - buildContext: () => Promise, -) => { - let context: LSP8InitializeTestContext; - - before(async () => { - context = await buildContext(); - }); - - describe('when the contract was initialized', () => { - 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, - ), - ).to.be.true; - }); - - it('should have set expected entries with ERC725Y.setData', async () => { - await expect(context.initializeTransaction) - .to.emit(context.lsp8CompatibleERC721, 'DataChanged') - .withArgs( - SupportedStandards.LSP4DigitalAsset.key, - SupportedStandards.LSP4DigitalAsset.value, - ); - expect( - await context.lsp8CompatibleERC721.getData(SupportedStandards.LSP4DigitalAsset.key), - ).to.equal(SupportedStandards.LSP4DigitalAsset.value); - - const nameKey = ERC725YDataKeys.LSP4['LSP4TokenName']; - const expectedNameValue = ethers.utils.hexlify( - ethers.utils.toUtf8Bytes(context.deployParams.name), - ); - await expect(context.initializeTransaction) - .to.emit(context.lsp8CompatibleERC721, 'DataChanged') - .withArgs(nameKey, expectedNameValue); - expect(await context.lsp8CompatibleERC721.getData(nameKey)).to.equal(expectedNameValue); - - const symbolKey = ERC725YDataKeys.LSP4['LSP4TokenSymbol']; - const expectedSymbolValue = ethers.utils.hexlify( - ethers.utils.toUtf8Bytes(context.deployParams.symbol), - ); - await expect(context.initializeTransaction) - .to.emit(context.lsp8CompatibleERC721, 'DataChanged') - .withArgs(symbolKey, expectedSymbolValue); - expect(await context.lsp8CompatibleERC721.getData(symbolKey)).to.equal(expectedSymbolValue); - - const tokenTypeKey = ERC725YDataKeys.LSP4['LSP4TokenType']; - const expectedTokenTypeValue = abiCoder.encode( - ['uint256'], - [context.deployParams.lsp4TokenType], - ); - await expect(context.initializeTransaction) - .to.emit(context.lsp8CompatibleERC721, 'DataChanged') - .withArgs(tokenTypeKey, expectedTokenTypeValue); - expect(await context.lsp8CompatibleERC721.getData(tokenTypeKey)).to.equal( - expectedTokenTypeValue, - ); - }); - - 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/LSP8IdentifiableDigitalAsset/proxy/LSP8CompatibleERC721Init.test.ts b/tests/LSP8IdentifiableDigitalAsset/proxy/LSP8CompatibleERC721Init.test.ts deleted file mode 100644 index 6cd11fa7d..000000000 --- a/tests/LSP8IdentifiableDigitalAsset/proxy/LSP8CompatibleERC721Init.test.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { ethers } from 'hardhat'; -import { expect } from 'chai'; - -import { - LSP8CompatibleERC721InitTester__factory, - LSP8CompatibleERC721MintableInit__factory, -} from '../../../types'; - -import { - getNamedAccounts, - shouldBehaveLikeLSP8CompatibleERC721, - shouldInitializeLikeLSP8CompatibleERC721, - LSP8CompatibleERC721TestContext, -} from '../LSP8CompatibleERC721.behaviour'; - -import { deployProxy } from '../../utils/fixtures'; -import { LSP4_TOKEN_TYPES, LSP8_TOKEN_ID_FORMAT } from '../../../constants'; - -describe('LSP8CompatibleERC721Init with proxy', () => { - const buildTestContext = async (): Promise => { - const accounts = await getNamedAccounts(); - - const tokenUriHex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes('ipfs://some-cid')); - const tokenUriHash = ethers.utils.keccak256(tokenUriHex); - const hashSig = ethers.utils.keccak256(ethers.utils.toUtf8Bytes('keccak256(utf8)')); - const lsp4MetadataValue = `${hashSig.slice(0, 10)}${tokenUriHash.replace( - /^0x/, - '', - )}${tokenUriHex.replace(/^0x/, '')}`; - - const deployParams = { - name: 'LSP8 - deployed with constructor', - symbol: 'NFT', - newOwner: accounts.owner.address, - lsp4TokenType: LSP4_TOKEN_TYPES.NFT, - lsp8TokenIdFormat: LSP8_TOKEN_ID_FORMAT.NUMBER, - lsp4MetadataValue, - }; - - const lsp8CompatibleERC721TesterInit = await new LSP8CompatibleERC721InitTester__factory( - accounts.owner, - ).deploy(); - const lsp8CompatibleERC721Proxy = await deployProxy( - lsp8CompatibleERC721TesterInit.address, - accounts.owner, - ); - const lsp8CompatibleERC721 = lsp8CompatibleERC721TesterInit.attach(lsp8CompatibleERC721Proxy); - - return { accounts, lsp8CompatibleERC721, deployParams }; - }; - - const initializeProxy = async (context: LSP8CompatibleERC721TestContext) => { - return context.lsp8CompatibleERC721['initialize(string,string,address,uint256,uint256,bytes)']( - context.deployParams.name, - context.deployParams.symbol, - context.deployParams.newOwner, - context.deployParams.lsp4TokenType, - context.deployParams.lsp8TokenIdFormat, - context.deployParams.lsp4MetadataValue, - ); - }; - - describe('when deploying the base implementation contract', () => { - it('LSP8CompatibleERC721Init: prevent any address from calling the initialize(...) function on the implementation', async () => { - const accounts = await ethers.getSigners(); - - const lsp8CompatibilityForERC721TesterInit = - await new LSP8CompatibleERC721InitTester__factory(accounts[0]).deploy(); - - const randomCaller = accounts[1]; - - await expect( - lsp8CompatibilityForERC721TesterInit.initialize( - 'XXXXXXXXXXX', - 'XXX', - randomCaller.address, - 12345, - 6789, - '0x', - ), - ).to.be.revertedWith('Initializable: contract is already initialized'); - }); - - it('LSP8CompatibleERC721MintableInit: prevent any address from calling the initialize(...) function on the implementation', async () => { - const accounts = await ethers.getSigners(); - - const lsp8CompatibleERC721MintableInit = await new LSP8CompatibleERC721MintableInit__factory( - accounts[0], - ).deploy(); - - const randomCaller = accounts[1]; - - await expect( - lsp8CompatibleERC721MintableInit.initialize( - 'XXXXXXXXXXX', - 'XXX', - randomCaller.address, - 12345, - 6789, - ), - ).to.be.revertedWith('Initializable: contract is already initialized'); - }); - }); - - describe('when deploying the contract as proxy', () => { - let context: LSP8CompatibleERC721TestContext; - - before(async () => { - context = await buildTestContext(); - }); - - describe('when initializing the contract', () => { - shouldInitializeLikeLSP8CompatibleERC721(async () => { - const { lsp8CompatibleERC721, deployParams } = context; - const initializeTransaction = await initializeProxy(context); - - return { - lsp8CompatibleERC721, - deployParams, - initializeTransaction, - }; - }); - }); - - describe('when calling initialize more than once', () => { - it('should revert', async () => { - await expect(initializeProxy(context)).to.be.revertedWith( - 'Initializable: contract is already initialized', - ); - }); - }); - }); - - describe('when testing deployed contract', () => { - shouldBehaveLikeLSP8CompatibleERC721(() => - buildTestContext().then(async (context) => { - await initializeProxy(context); - - return context; - }), - ); - }); -}); diff --git a/tests/LSP8IdentifiableDigitalAsset/standard/LSP8CompatibleERC721.test.ts b/tests/LSP8IdentifiableDigitalAsset/standard/LSP8CompatibleERC721.test.ts deleted file mode 100644 index 0565ccd67..000000000 --- a/tests/LSP8IdentifiableDigitalAsset/standard/LSP8CompatibleERC721.test.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { ethers } from 'hardhat'; - -import { LSP8CompatibleERC721Tester__factory } from '../../../types'; - -import { - getNamedAccounts, - shouldBehaveLikeLSP8CompatibleERC721, - shouldInitializeLikeLSP8CompatibleERC721, - LSP8CompatibleERC721TestContext, -} from '../LSP8CompatibleERC721.behaviour'; -import { LSP4_TOKEN_TYPES, LSP8_TOKEN_ID_FORMAT } from '../../../constants'; - -describe('LSP8CompatibleERC721 with constructor', () => { - const buildTestContext = async (): Promise => { - const accounts = await getNamedAccounts(); - - const tokenUriHex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes('ipfs://some-cid')); - const tokenUriHash = ethers.utils.keccak256(tokenUriHex); - const hashSig = ethers.utils.keccak256(ethers.utils.toUtf8Bytes('keccak256(utf8)')); - const lsp4MetadataValue = `${hashSig.slice(0, 10)}${tokenUriHash.replace( - /^0x/, - '', - )}${tokenUriHex.replace(/^0x/, '')}`; - - const deployParams = { - name: 'Compat for ERC721', - symbol: 'NFT', - newOwner: accounts.owner.address, - lsp4TokenType: LSP4_TOKEN_TYPES.NFT, - lsp8TokenIdFormat: LSP8_TOKEN_ID_FORMAT.NUMBER, - lsp4MetadataValue, - }; - - const lsp8CompatibleERC721 = await new LSP8CompatibleERC721Tester__factory( - accounts.owner, - ).deploy( - deployParams.name, - deployParams.symbol, - deployParams.newOwner, - deployParams.lsp4TokenType, - deployParams.lsp8TokenIdFormat, - deployParams.lsp4MetadataValue, - ); - - return { accounts, lsp8CompatibleERC721, deployParams }; - }; - - describe('when deploying the contract', () => { - let context: LSP8CompatibleERC721TestContext; - - before(async () => { - context = await buildTestContext(); - }); - - describe('when initializing the contract', () => { - shouldInitializeLikeLSP8CompatibleERC721(async () => { - const { lsp8CompatibleERC721, deployParams } = context; - - return { - lsp8CompatibleERC721, - deployParams, - initializeTransaction: context.lsp8CompatibleERC721.deployTransaction, - }; - }); - }); - }); - - describe('when testing deployed contract', () => { - shouldBehaveLikeLSP8CompatibleERC721(buildTestContext); - }); -});