Skip to content

Commit

Permalink
feat: move LSP4 to its own monorepo package
Browse files Browse the repository at this point in the history
  • Loading branch information
b00ste committed Jan 23, 2024
1 parent 4c31ce7 commit afb9dbf
Show file tree
Hide file tree
Showing 15 changed files with 582 additions and 0 deletions.
71 changes: 71 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/LSP4DigitalAssetMetadata/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: ['custom'],
};
3 changes: 3 additions & 0 deletions packages/LSP4DigitalAssetMetadata/.gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib/forge-std"]
path = ../../lib/forge-std
url = https://github.com/foundry-rs/forge-std.git
25 changes: 25 additions & 0 deletions packages/LSP4DigitalAssetMetadata/.solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"extends": "solhint:recommended",
"rules": {
"avoid-sha3": "error",
"avoid-suicide": "error",
"avoid-throw": "error",
"avoid-tx-origin": "error",
"check-send-result": "error",
"compiler-version": ["error", "^0.8.0"],
"func-visibility": ["error", { "ignoreConstructors": true }],
"not-rely-on-block-hash": "error",
"not-rely-on-time": "error",
"reentrancy": "error",
"constructor-syntax": "error",
"private-vars-leading-underscore": ["error", { "strict": false }],
"imports-on-top": "error",
"visibility-modifier-order": "error",
"no-unused-import": "error",
"no-global-import": "error",
"reason-string": ["warn", { "maxLength": 120 }],
"avoid-low-level-calls": "off",
"no-empty-blocks": ["error", { "ignoreConstructors": true }],
"custom-errors": "off"
}
}
51 changes: 51 additions & 0 deletions packages/LSP4DigitalAssetMetadata/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# LSP Package Template

This project can be used as a skeleton to build a package for a LSP implementation in Solidity (LUKSO Standard Proposal)

It is based on Hardhat.

## How to setup a LSP as a package?

1. Copy the `template/` folder and paste it under the `packages/` folder. Then rename this `template/` folder that you copied with the LSP name.

You can do so either:

- manually, by copying the folder and pasting it inside `packages` and then renaming it.
or
- by running the following command from the root of the repository.

```bash
cp -r template packages/lsp-name
```

2. Update the `"name"` and `"description"` field inside the `package.json` for this LSP package you just created.

3. Setup the dependencies

If this LSP uses external dependencies like `@openzeppelin/contracts`, put them under `dependencies` with the version number.

```json
"@openzeppelin/contracts": "^4.9.3"
```

If this LSP uses other LSP as dependencies, put each LSP dependency as shown below. This will use the current code in the package:

```json
"@lsp2": "*"
```

4. Setup the npm commands for linting, building, testing, etc... under the `"scripts"` in the `package.json`

5. Test that all commands you setup run successfully

By running the commands below, your LSP package should come up in the list of packages that Turbo is running this command for.

```bash
turbo build
turbo lint
turbo lint:solidity
turbo test
turbo test:foundry
```

6. Finally update the relevant information in the `README.md` file in the folder of the newly created package, such as the title at the top, some description, etc...
33 changes: 33 additions & 0 deletions packages/LSP4DigitalAssetMetadata/contracts/LSP4Constants.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// 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'))
bytes32 constant _LSP4_SUPPORTED_STANDARDS_KEY = 0xeafec4d89fa9619884b60000a4d96624a38f7ac2d8d9a604ecf07c12c77e480c;

// bytes4(keccak256('LSP4DigitalAsset'))
bytes constant _LSP4_SUPPORTED_STANDARDS_VALUE = hex"a4d96624";

// keccak256('LSP4TokenName')
bytes32 constant _LSP4_TOKEN_NAME_KEY = 0xdeba1e292f8ba88238e10ab3c7f88bd4be4fac56cad5194b6ecceaf653468af1;

// 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;

// bytes10(keccak256('LSP4CreatorsMap'))
bytes10 constant _LSP4_CREATORS_MAP_KEY_PREFIX = 0x6de85eaf5d982b4e5da0;

// keccak256('LSP4Metadata')
bytes32 constant _LSP4_METADATA_KEY = 0x9afb95cacc9f95858ec44aa8c3b685511002e30ae54415823f406128b85b238e;
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;

// modules
import {ERC725Y} from "@erc725/smart-contracts/contracts/ERC725Y.sol";
import {ERC725YCore} from "@erc725/smart-contracts/contracts/ERC725YCore.sol";
import {LSP4DigitalAssetMetadataCore} from "./LSP4DigitalAssetMetadataCore.sol";

// constants
import {
_LSP4_SUPPORTED_STANDARDS_KEY,
_LSP4_SUPPORTED_STANDARDS_VALUE,
_LSP4_TOKEN_NAME_KEY,
_LSP4_TOKEN_SYMBOL_KEY,
_LSP4_TOKEN_TYPE_KEY
} from "./LSP4Constants.sol";

/**
* @title Implementation of a LSP4DigitalAssetMetadata contract that stores the **Token-Metadata** (`LSP4TokenName` and `LSP4TokenSymbol`) in its ERC725Y data store.
* @author Matthew Stevens
* @dev Standard Implementation of the LSP4 standard.
*/
abstract contract LSP4DigitalAssetMetadata is
ERC725Y,
LSP4DigitalAssetMetadataCore
{
/**
* @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 lsp4TokenType_ The type of token this digital asset contract represents (`0` = Token, `1` = NFT, `2` = Collection).
*/
constructor(
string memory name_,
string memory symbol_,
address initialOwner_,
uint256 lsp4TokenType_
) ERC725Y(initialOwner_) {
// set data key SupportedStandards:LSP4DigitalAsset
ERC725YCore._setData(
_LSP4_SUPPORTED_STANDARDS_KEY,
_LSP4_SUPPORTED_STANDARDS_VALUE
);

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_));
}

/**
* @dev The ERC725Y data keys `LSP4TokenName` and `LSP4TokenSymbol` cannot be changed
* via this function once the digital asset contract has been deployed.
*/
function _setData(
bytes32 dataKey,
bytes memory dataValue
) internal virtual override(ERC725YCore, LSP4DigitalAssetMetadataCore) {
LSP4DigitalAssetMetadataCore._setData(dataKey, dataValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;

// modules
import {ERC725YCore} from "@erc725/smart-contracts/contracts/ERC725YCore.sol";

// constants
import {
_LSP4_TOKEN_NAME_KEY,
_LSP4_TOKEN_SYMBOL_KEY,
_LSP4_TOKEN_TYPE_KEY
} from "./LSP4Constants.sol";

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

/**
* @title Implementation of a LSP4DigitalAssetMetadata contract that stores the **Token-Metadata** (`LSP4TokenName` and `LSP4TokenSymbol`) in its ERC725Y data store.
* @author Matthew Stevens
* @dev Standard Implementation of the LSP4 standard.
*/
abstract contract LSP4DigitalAssetMetadataCore is ERC725YCore {
/**
* @dev The ERC725Y data keys `LSP4TokenName` and `LSP4TokenSymbol` cannot be changed
* via this function once the digital asset contract has been deployed.
*/
function _setData(
bytes32 dataKey,
bytes memory dataValue
) internal virtual override {
if (dataKey == _LSP4_TOKEN_NAME_KEY) {
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);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;

// modules
import {
ERC725YInitAbstract
} from "@erc725/smart-contracts/contracts/ERC725YInitAbstract.sol";

import {ERC725YCore} from "@erc725/smart-contracts/contracts/ERC725YCore.sol";

import {LSP4DigitalAssetMetadataCore} from "./LSP4DigitalAssetMetadataCore.sol";

// constants
import {
_LSP4_SUPPORTED_STANDARDS_KEY,
_LSP4_SUPPORTED_STANDARDS_VALUE,
_LSP4_TOKEN_NAME_KEY,
_LSP4_TOKEN_SYMBOL_KEY,
_LSP4_TOKEN_TYPE_KEY
} from "./LSP4Constants.sol";

/**
* @title Implementation of a LSP4DigitalAssetMetadata contract that stores the **Token-Metadata** (`LSP4TokenName` and `LSP4TokenSymbol`) in its ERC725Y data store.
* @author Matthew Stevens
* @dev Inheritable Proxy Implementation of the LSP4 standard.
*/
abstract contract LSP4DigitalAssetMetadataInitAbstract is
LSP4DigitalAssetMetadataCore,
ERC725YInitAbstract
{
/**
* @notice Initializing 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 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_,
uint256 lsp4TokenType_
) internal virtual onlyInitializing {
ERC725YInitAbstract._initialize(initialOwner_);

// set data key SupportedStandards:LSP4DigitalAsset
ERC725YCore._setData(
_LSP4_SUPPORTED_STANDARDS_KEY,
_LSP4_SUPPORTED_STANDARDS_VALUE
);

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_));
}

/**
* @dev The ERC725Y data keys `LSP4TokenName` and `LSP4TokenSymbol` cannot be changed
* via this function once the digital asset contract has been deployed.
*/
function _setData(
bytes32 dataKey,
bytes memory dataValue
) internal virtual override(ERC725YCore, LSP4DigitalAssetMetadataCore) {
LSP4DigitalAssetMetadataCore._setData(dataKey, dataValue);
}
}
Loading

0 comments on commit afb9dbf

Please sign in to comment.