Skip to content

Commit

Permalink
feat!: set LSP4TokenType on deployment of LSP7/8 Digital Assets (#806)
Browse files Browse the repository at this point in the history
* refactor!: set `LSP4TokenType` on deployment of digital asset

* test: add tests for LSP4 for `LSP4TokenType` data key not editable

* test: update LSP7 test suite with extra deployment param

* test: update LSP8 test with extra deployment param

* docs: update auto-generated docs

* test: fix remaining tests that deploy tokens

* test: update tokens deployments on foundry tests

* refactor: put `lsp4TokenType` param before `lsp8TokenIdType` on deployment

* refactor: rename LSP8TokenIdType to LSP8TokenIdSchema

* chore: resolve merge conflicts

* test: fix foundry tesst

* docs: add autogenerated docs

---------

Co-authored-by: YamenMerhi <yamennmerhi@gmail.com>
  • Loading branch information
CJ42 and YamenMerhi authored Nov 29, 2023
1 parent 642da9d commit 9ee6558
Show file tree
Hide file tree
Showing 105 changed files with 1,135 additions and 386 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ import {
ERC725YDataKeys,
PERMISSIONS,
ALL_PERMISSIONS,
LSP8_TOKEN_ID_TYPES,
LSP8_TOKEN_ID_SCHEMA,
LSP25_VERSION,
ErrorSelectors,
EventSigHashes,
Expand Down
36 changes: 28 additions & 8 deletions constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ export const ERC725YDataKeys = {
// keccak256('LSP4TokenSymbol')
LSP4TokenSymbol: '0x2f0a68ab07768e01943a599e73362a0e17a63a72e94dd2e384d2c1d4db932756',

// keccak256('LSP4TokenType)
LSP4TokenType: '0xe0261fa95db2eb3b5439bd033cda66d56b96f92f243a8228fd87550ed7bdfdb3',

// keccak256('LSP4Metadata')
LSP4Metadata: '0x9afb95cacc9f95858ec44aa8c3b685511002e30ae54415823f406128b85b238e',

Expand Down Expand Up @@ -233,8 +236,7 @@ export const ERC725YDataKeys = {
'AddressPermissions:AllowedCalls': '0x4b80742de2bf393a64c70000',
},
LSP8: {
LSP8TokenIdType: '0x715f248956de7ce65e94d9d836bfead479f7e70d69b718d47bfe7b00e05b4fe4',
LSP8MetadataTokenURI: '0x1339e76a390b7b9ec9010000',
LSP8TokenIdSchema: '0x341bc44e55234544c70af9d37b2cb8cc7ba74685b58526221de2cc977f469924',
LSP8TokenMetadataBaseURI: '0x1a7628600c3bac7101f53697f48df381ddc36b9015e7d7c9c5633d1252aa2843',
LSP8ReferenceContract: '0x708e7b881795f2e6b6c2752108c177ec89248458de3bf69d0d43480b3e5034e6',
},
Expand Down Expand Up @@ -390,19 +392,37 @@ export const LSP1_TYPE_IDS = {
'0xe32c7debcb817925ba4883fdbfc52797187f28f73f860641dab1a68d9b32902c',
};

// LSP4
// ----------

/**
* @dev list of LSP4 Token types to describe the type of token a digital asset contract represents.
* @see for details see: https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-4-DigitalAsset-Metadata.md#lsp4tokentype
*/
export const LSP4_TOKEN_TYPES = {
TOKEN: 0,
NFT: 1,
COLLECTION: 2,
};

// LSP8
// ----------

/**
* @dev list of LSP8 Token ID types that can be used to create different types of NFTs.
* @see for details see: https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenidtype
* @dev list of LSP8 Token ID Schemas that can be used to create different types of NFTs and represent each NFT identifiers differently.
* @see for details see: https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-8-IdentifiableDigitalAsset.md#lsp8tokenidschema
*/
export const LSP8_TOKEN_ID_TYPES = {
export const LSP8_TOKEN_ID_SCHEMA = {
NUMBER: 0,
STRING: 1,
UNIQUE_ID: 2,
HASH: 3,
ADDRESS: 4,
ADDRESS: 2,
UNIQUE_ID: 3,
HASH: 4,
MIXED_DEFAULT_NUMBER: 100,
MIXED_DEFAULT_STRING: 101,
MIXED_DEFAULT_ADDRESS: 102,
MIXED_DEFAULT_UNIQUE_ID: 103,
MIXED_DEFAULT_HASH: 104,
};

// LSP25
Expand Down
9 changes: 9 additions & 0 deletions contracts/LSP4DigitalAssetMetadata/LSP4Constants.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;

// Token types

uint256 constant _LSP4_TOKEN_TYPE_TOKEN = 0;
uint256 constant _LSP4_TOKEN_TYPE_NFT = 1;
uint256 constant _LSP4_TOKEN_TYPE_COLLECTION = 2;

// --- ERC725Y entries

// bytes10(keccak256('SupportedStandards')) + bytes2(0) + bytes20(keccak256('LSP4DigitalAsset'))
Expand All @@ -15,6 +21,9 @@ bytes32 constant _LSP4_TOKEN_NAME_KEY = 0xdeba1e292f8ba88238e10ab3c7f88bd4be4fac
// keccak256('LSP4TokenSymbol')
bytes32 constant _LSP4_TOKEN_SYMBOL_KEY = 0x2f0a68ab07768e01943a599e73362a0e17a63a72e94dd2e384d2c1d4db932756;

// keccak256('LSP4TokenType')
bytes32 constant _LSP4_TOKEN_TYPE_KEY = 0xe0261fa95db2eb3b5439bd033cda66d56b96f92f243a8228fd87550ed7bdfdb3;

// keccak256('LSP4Creators[]')
bytes32 constant _LSP4_CREATORS_ARRAY_KEY = 0x114bd03b3a46d48759680d81ebb2b414fda7d030a7105a851867accf1c2352e7;

Expand Down
14 changes: 9 additions & 5 deletions contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
_LSP4_SUPPORTED_STANDARDS_KEY,
_LSP4_SUPPORTED_STANDARDS_VALUE,
_LSP4_TOKEN_NAME_KEY,
_LSP4_TOKEN_SYMBOL_KEY
_LSP4_TOKEN_SYMBOL_KEY,
_LSP4_TOKEN_TYPE_KEY
} from "./LSP4Constants.sol";

/**
Expand All @@ -26,14 +27,16 @@ abstract contract LSP4DigitalAssetMetadata is
/**
* @notice Deploying a digital asset `name_` with the `symbol_` symbol.
*
* @param name_ The name of the token
* @param symbol_ The symbol of the token
* @param initialOwner_ The owner of the token contract
* @param name_ The name of the token.
* @param symbol_ The symbol of the token.
* @param initialOwner_ The owner of the token contract.
* @param lsp4TokenType_ The type of token this digital asset contract represents (`1` = Token, `2` = NFT, `3` = Collection).
*/
constructor(
string memory name_,
string memory symbol_,
address initialOwner_
address initialOwner_,
uint256 lsp4TokenType_
) ERC725Y(initialOwner_) {
// set data key SupportedStandards:LSP4DigitalAsset
ERC725YCore._setData(
Expand All @@ -43,6 +46,7 @@ abstract contract LSP4DigitalAssetMetadata is

ERC725YCore._setData(_LSP4_TOKEN_NAME_KEY, bytes(name_));
ERC725YCore._setData(_LSP4_TOKEN_SYMBOL_KEY, bytes(symbol_));
ERC725YCore._setData(_LSP4_TOKEN_TYPE_KEY, abi.encode(lsp4TokenType_));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";
// constants
import {
_LSP4_TOKEN_NAME_KEY,
_LSP4_TOKEN_SYMBOL_KEY
_LSP4_TOKEN_SYMBOL_KEY,
_LSP4_TOKEN_TYPE_KEY
} from "./LSP4Constants.sol";

// errors
import {
LSP4TokenNameNotEditable,
LSP4TokenSymbolNotEditable
LSP4TokenSymbolNotEditable,
LSP4TokenTypeNotEditable
} from "./LSP4Errors.sol";

/**
Expand All @@ -39,8 +41,11 @@ abstract contract LSP4DigitalAssetMetadataCore is ERC725YCore {
revert LSP4TokenNameNotEditable();
} else if (dataKey == _LSP4_TOKEN_SYMBOL_KEY) {
revert LSP4TokenSymbolNotEditable();
} else if (dataKey == _LSP4_TOKEN_TYPE_KEY) {
revert LSP4TokenTypeNotEditable();
} else {
_store[dataKey] = dataValue;

emit DataChanged(
dataKey,
dataValue.length <= 256
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
_LSP4_SUPPORTED_STANDARDS_KEY,
_LSP4_SUPPORTED_STANDARDS_VALUE,
_LSP4_TOKEN_NAME_KEY,
_LSP4_TOKEN_SYMBOL_KEY
_LSP4_TOKEN_SYMBOL_KEY,
_LSP4_TOKEN_TYPE_KEY
} from "./LSP4Constants.sol";

/**
Expand All @@ -33,11 +34,13 @@ abstract contract LSP4DigitalAssetMetadataInitAbstract is
* @param name_ The name of the token
* @param symbol_ The symbol of the token
* @param initialOwner_ The owner of the token contract
* @param lsp4TokenType_ The type of token this digital asset contract represents (`1` = Token, `2` = NFT, `3` = Collection)
*/
function _initialize(
string memory name_,
string memory symbol_,
address initialOwner_
address initialOwner_,
uint256 lsp4TokenType_
) internal virtual onlyInitializing {
ERC725YInitAbstract._initialize(initialOwner_);

Expand All @@ -49,6 +52,7 @@ abstract contract LSP4DigitalAssetMetadataInitAbstract is

ERC725YCore._setData(_LSP4_TOKEN_NAME_KEY, bytes(name_));
ERC725YCore._setData(_LSP4_TOKEN_SYMBOL_KEY, bytes(symbol_));
ERC725YCore._setData(_LSP4_TOKEN_TYPE_KEY, abi.encode(lsp4TokenType_));
}

/**
Expand Down
19 changes: 13 additions & 6 deletions contracts/LSP4DigitalAssetMetadata/LSP4Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@
pragma solidity ^0.8.4;

/**
* @dev Reverts when trying to edit the data key `LSP4TokenName` after the digital asset contract has been deployed.
* 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.
* @dev 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.
*/
error LSP4TokenNameNotEditable();

/**
* @dev Reverts when trying to edit the data key `LSP4TokenSymbol` after the digital asset contract has been deployed.
* 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.
* @dev 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.
*/
error LSP4TokenSymbolNotEditable();

/**
* @dev 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.
*/
error LSP4TokenTypeNotEditable();
12 changes: 7 additions & 5 deletions contracts/LSP7DigitalAsset/LSP7DigitalAsset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,19 @@ abstract contract LSP7DigitalAsset is
{
/**
* @notice Sets the token-Metadata
* @param name_ The name of the token
* @param symbol_ The symbol of the token
* @param newOwner_ The owner of the the token-Metadata
* @param isNonDivisible_ Specify if the LSP7 token is a fungible or non-fungible token
* @param name_ The name of the token.
* @param symbol_ The symbol of the token.
* @param newOwner_ The owner of the the token-Metadata.
* @param lsp4TokenType_ The type of token this digital asset contract represents (`1` = Token, `2` = NFT, `3` = Collection).
* @param isNonDivisible_ Specify if the LSP7 token is a fungible or non-fungible token.
*/
constructor(
string memory name_,
string memory symbol_,
address newOwner_,
uint256 lsp4TokenType_,
bool isNonDivisible_
) LSP4DigitalAssetMetadata(name_, symbol_, newOwner_) {
) LSP4DigitalAssetMetadata(name_, symbol_, newOwner_, lsp4TokenType_) {
_isNonDivisible = isNonDivisible_;
}

Expand Down
7 changes: 5 additions & 2 deletions contracts/LSP7DigitalAsset/LSP7DigitalAssetInitAbstract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,17 @@ abstract contract LSP7DigitalAssetInitAbstract is
string memory name_,
string memory symbol_,
address newOwner_,
uint256 lsp4TokenType_,
bool isNonDivisible_
) internal virtual onlyInitializing {
_isNonDivisible = isNonDivisible_;
LSP4DigitalAssetMetadataInitAbstract._initialize(
name_,
symbol_,
newOwner_
newOwner_,
lsp4TokenType_
);

_isNonDivisible = isNonDivisible_;
}

// fallback function
Expand Down
6 changes: 4 additions & 2 deletions contracts/LSP7DigitalAsset/extensions/LSP7CompatibleERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ abstract contract LSP7CompatibleERC20 is IERC20Metadata, LSP7DigitalAsset {
* @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 (`1` = Token, `2` = NFT, `3` = Collection).
*/
constructor(
string memory name_,
string memory symbol_,
address newOwner_
) LSP7DigitalAsset(name_, symbol_, newOwner_, false) {}
address newOwner_,
uint256 lsp4TokenType_
) LSP7DigitalAsset(name_, symbol_, newOwner_, lsp4TokenType_, false) {}

/**
* @inheritdoc IERC20Metadata
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,22 @@ abstract contract LSP7CompatibleERC20InitAbstract is
* @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 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 (`1` = Token, `2` = NFT, `3` = Collection).
*/
function _initialize(
string memory name_,
string memory symbol_,
address newOwner_
address newOwner_,
uint256 lsp4TokenType_
) internal virtual override onlyInitializing {
LSP7DigitalAssetInitAbstract._initialize(
name_,
symbol_,
newOwner_,
lsp4TokenType_,
false
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ contract LSP7CompatibleERC20Mintable is LSP7CompatibleERC20 {
* @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 (`1` = Token, `2` = NFT, `3` = Collection).
*/
constructor(
string memory name_,
string memory symbol_,
address newOwner_
) LSP7CompatibleERC20(name_, symbol_, newOwner_) {}
address newOwner_,
uint256 lsp4TokenType_
) LSP7CompatibleERC20(name_, symbol_, newOwner_, lsp4TokenType_) {}

/**
* @dev Public {_mint} function only callable by the {owner}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,19 @@ contract LSP7CompatibleERC20MintableInit is
* @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 (`1` = Token, `2` = NFT, `3` = Collection).
*/
function initialize(
string memory name_,
string memory symbol_,
address newOwner_
address newOwner_,
uint256 lsp4TokenType_
) external virtual initializer {
LSP7CompatibleERC20MintableInitAbstract._initialize(
name_,
symbol_,
newOwner_
newOwner_,
lsp4TokenType_
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ abstract contract LSP7CompatibleERC20MintableInitAbstract is
function _initialize(
string memory name_,
string memory symbol_,
address newOwner_
address newOwner_,
uint256 lsp4TokenType_
) internal virtual override onlyInitializing {
LSP7CompatibleERC20InitAbstract._initialize(name_, symbol_, newOwner_);
LSP7CompatibleERC20InitAbstract._initialize(
name_,
symbol_,
newOwner_,
lsp4TokenType_
);
}

/**
Expand Down
13 changes: 12 additions & 1 deletion contracts/LSP7DigitalAsset/presets/LSP7Mintable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,24 @@ contract LSP7Mintable is LSP7DigitalAsset, ILSP7Mintable {
* @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 (`1` = Token, `2` = NFT, `3` = Collection).
* @param isNonDivisible_ Specify if the LSP7 token is a fungible or non-fungible token.
*/
constructor(
string memory name_,
string memory symbol_,
address newOwner_,
uint256 lsp4TokenType_,
bool isNonDivisible_
) LSP7DigitalAsset(name_, symbol_, newOwner_, isNonDivisible_) {}
)
LSP7DigitalAsset(
name_,
symbol_,
newOwner_,
lsp4TokenType_,
isNonDivisible_
)
{}

/**
* @dev Public {_mint} function only callable by the {owner}.
Expand Down
Loading

0 comments on commit 9ee6558

Please sign in to comment.