Skip to content

Commit

Permalink
Merge branch 'asset-l2-integration' into asset-audit-n-04
Browse files Browse the repository at this point in the history
  • Loading branch information
wojciech-turek authored Sep 15, 2023
2 parents e3e9b80 + fc06649 commit f63b04d
Show file tree
Hide file tree
Showing 52 changed files with 1,130 additions and 700 deletions.
36 changes: 29 additions & 7 deletions packages/asset/contracts/Asset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ import {TokenIdUtils} from "./libraries/TokenIdUtils.sol";
import {IAsset} from "./interfaces/IAsset.sol";
import {ITokenUtils, IRoyaltyUGC} from "./interfaces/ITokenUtils.sol";

/// @title Asset
/// @author The Sandbox
/// @notice ERC1155 asset token contract
/// @notice Minting and burning tokens is only allowed through separate authorized contracts
/// @dev This contract is final and should not be inherited
contract Asset is
IAsset,
Initializable,
Expand All @@ -56,6 +61,12 @@ contract Asset is
_disableInitializers();
}

/// @notice Initialize the contract
/// @param forwarder The address of the trusted forwarder
/// @param assetAdmin The address of the asset admin
/// @param baseUri The base URI for the token metadata
/// @param commonSubscription The address of the operator filter subscription
/// @param _manager The address of the royalty manager
function initialize(
address forwarder,
address assetAdmin,
Expand All @@ -78,6 +89,7 @@ contract Asset is
/// @param to The address of the recipient
/// @param id The id of the token to mint
/// @param amount The amount of the token to mint
/// @param metadataHash The metadata hash of the token to mint
function mint(
address to,
uint256 id,
Expand All @@ -95,6 +107,7 @@ contract Asset is
/// @param to The address of the recipient
/// @param ids The ids of the tokens to mint
/// @param amounts The amounts of the tokens to mint
/// @param metadataHashes The metadata hashes of the tokens to mint
function mintBatch(
address to,
uint256[] memory ids,
Expand Down Expand Up @@ -168,10 +181,16 @@ contract Asset is
return ERC1155URIStorageUpgradeable.uri(tokenId);
}

/// @notice returns the tokenId associated with provided metadata hash
/// @param metadataHash The metadata hash to get tokenId for
/// @return tokenId the tokenId associated with the metadata hash
function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256) {
return hashUsed[metadataHash];
}

/// @notice sets the metadata hash for a given tokenId
/// @param tokenId The tokenId to set metadata hash for
/// @param metadataHash The metadata hash to set
function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal {
if (hashUsed[metadataHash] != 0) {
require(hashUsed[metadataHash] == tokenId, "Asset: not allowed to reuse metadata hash");
Expand Down Expand Up @@ -310,32 +329,33 @@ contract Asset is

/// @notice Extracts the revealed flag from a given token id
/// @param tokenId The token id to extract the revealed flag from
/// @return isRevealed Whether the asset is revealed or not
function isRevealed(uint256 tokenId) external pure returns (bool) {
/// @return revealed Whether the asset is revealed or not
function isRevealed(uint256 tokenId) external pure returns (bool revealed) {
return TokenIdUtils.isRevealed(tokenId);
}

/// @notice Extracts the asset nonce from a given token id
/// @param tokenId The token id to extract the asset nonce from
/// @return creatorNonce The asset creator nonce
function getCreatorNonce(uint256 tokenId) external pure returns (uint16) {
function getCreatorNonce(uint256 tokenId) external pure returns (uint16 creatorNonce) {
return TokenIdUtils.getCreatorNonce(tokenId);
}

/// @notice Extracts the abilities and enhancements hash from a given token id
/// @param tokenId The token id to extract reveal nonce from
/// @return revealNonce The reveal nonce of the asset
function getRevealNonce(uint256 tokenId) external pure returns (uint16) {
function getRevealNonce(uint256 tokenId) external pure returns (uint16 revealNonce) {
return TokenIdUtils.getRevealNonce(tokenId);
}

/// @notice Extracts the bridged flag from a given token id
/// @param tokenId The token id to extract the bridged flag from
/// @return bridged Whether the asset is bridged or not
function isBridged(uint256 tokenId) external pure returns (bool) {
function isBridged(uint256 tokenId) external pure returns (bool bridged) {
return TokenIdUtils.isBridged(tokenId);
}


/// @notice This function is used to register Asset contract on the Operator Filterer Registry of OpenSea. Can only be called by admin.
/// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.
/// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.
Expand All @@ -348,10 +368,12 @@ contract Asset is
_registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);
}

/// @notice sets filter registry address deployed in test
/// @notice sets the operator filter registry address
/// @param registry the address of the registry
function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(registry != address(0), "Asset: registry can't be zero address");
operatorFilterRegistry = IOperatorFilterRegistry(registry);
OperatorFiltererUpgradeable._setOperatorFilterRegistry(registry);
}

uint256[49] private __gap;
}
26 changes: 20 additions & 6 deletions packages/asset/contracts/AssetCreate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ contract AssetCreate is
}

/// @notice Initialize the contract
/// @param _name The name of the contract (for EIP712)
/// @param _version The version of the contract (for EIP712)
/// @param _assetContract The address of the asset contract
/// @param _catalystContract The address of the catalyst contract
/// @param _authValidator The address of the AuthSuperValidator contract
/// @param _forwarder The address of the forwarder contract
/// @param _defaultAdmin The address of the default admin
function initialize(
string memory _name,
string memory _version,
Expand All @@ -80,7 +84,9 @@ contract AssetCreate is
/// @param signature A signature generated by TSB
/// @param tier The tier of the asset to mint
/// @param amount The amount of the asset to mint
/// @param revealed Whether the asset is revealed or not
/// @param metadataHash The metadata hash of the asset to mint
/// @param creator The address of the creator
function createAsset(
bytes memory signature,
uint8 tier,
Expand All @@ -94,7 +100,7 @@ contract AssetCreate is
signature,
_hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)
),
"Invalid signature"
"AssetCreate: Invalid signature"
);

uint256 tokenId =
Expand All @@ -110,7 +116,9 @@ contract AssetCreate is
/// @param signature A signature generated by TSB
/// @param tiers The tiers of the assets to mint
/// @param amounts The amounts of the assets to mint
/// @param revealed Whether the assets are revealed or not
/// @param metadataHashes The metadata hashes of the assets to mint
/// @param creator The address of the creator
function createMultipleAssets(
bytes memory signature,
uint8[] calldata tiers,
Expand All @@ -124,12 +132,12 @@ contract AssetCreate is
signature,
_hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes)
),
"Invalid signature"
"AssetCreate: Invalid signature"
);

require(tiers.length == amounts.length, "Arrays must be same length");
require(amounts.length == metadataHashes.length, "Arrays must be same length");
require(metadataHashes.length == revealed.length, "Arrays must be same length");
require(tiers.length == amounts.length, "AssetCreate: Arrays must be same length");
require(amounts.length == metadataHashes.length, "AssetCreate: Arrays must be same length");
require(metadataHashes.length == revealed.length, "AssetCreate: Arrays must be same length");

uint256[] memory tokenIds = new uint256[](tiers.length);
uint256[] memory tiersToBurn = new uint256[](tiers.length);
Expand Down Expand Up @@ -167,7 +175,7 @@ contract AssetCreate is
signature,
_hashMint(creator, signatureNonces[_msgSender()]++, 0, amount, true, metadataHash)
),
"Invalid signature"
"AssetCreate: Invalid signature"
);

uint256 tokenId = TokenIdUtils.generateTokenId(creator, 0, ++creatorNonces[creator], 1, false);
Expand Down Expand Up @@ -206,8 +214,10 @@ contract AssetCreate is

/// @notice Creates a hash of the mint data
/// @param creator The address of the creator
/// @param nonce The nonce of the creator
/// @param tier The tier of the asset
/// @param amount The amount of copies to mint
/// @param revealed Whether the asset is revealed or not
/// @param metadataHash The metadata hash of the asset
/// @return digest The hash of the mint data
function _hashMint(
Expand Down Expand Up @@ -235,8 +245,10 @@ contract AssetCreate is

/// @notice Creates a hash of the mint batch data
/// @param creator The address of the creator
/// @param nonce The nonce of the creator
/// @param tiers The tiers of the assets
/// @param amounts The amounts of copies to mint
/// @param revealed Whether the assets are revealed or not
/// @param metadataHashes The metadata hashes of the assets
/// @return digest The hash of the mint batch data
function _hashBatchMint(
Expand Down Expand Up @@ -301,4 +313,6 @@ contract AssetCreate is
{
return ERC2771HandlerUpgradeable._msgData();
}

uint256[45] private __gap;
}
9 changes: 9 additions & 0 deletions packages/asset/contracts/AuthSuperValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,13 @@ contract AuthSuperValidator is AccessControl {
address recoveredSigner = ECDSA.recover(digest, signature);
return recoveredSigner == signer;
}

/// @notice Prevents the DEFAULT_ADMIN_ROLE from being renounced
/// @dev This function overrides the default renounceRole function to prevent the DEFAULT_ADMIN_ROLE from being renounced
/// @param role Role to renounce
/// @param account Account to renounce the role for
function renounceRole(bytes32 role, address account) public override {
require(role != DEFAULT_ADMIN_ROLE, "AuthSuperValidator: can't renounce admin role");
super.renounceRole(role, account);
}
}
26 changes: 18 additions & 8 deletions packages/asset/contracts/Catalyst.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {ICatalyst} from "./interfaces/ICatalyst.sol";

/// @title Catalyst
/// @author The Sandbox
/// @notice THis contract manages catalysts which are used to mint new assets.
/// @notice This contract manages catalysts which are used to mint new assets.
/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to
/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.
/// The contract includes support for meta transactions.
Expand Down Expand Up @@ -77,7 +77,7 @@ contract Catalyst is
address _defaultMinter,
string[] memory _catalystIpfsCID,
address _royaltyManager
) public initializer {
) external initializer {
require(bytes(_baseUri).length != 0, "Catalyst: base uri can't be empty");
require(_trustedForwarder != address(0), "Catalyst: trusted forwarder can't be zero");
require(_subscription != address(0), "Catalyst: subscription can't be zero");
Expand Down Expand Up @@ -154,7 +154,7 @@ contract Catalyst is
}

/// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only
/// @param ipfsCID The royalty bps for the catalyst
/// @param ipfsCID The IPFS content identifiers for the catalyst
function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(bytes(ipfsCID).length != 0, "Catalyst: CID can't be empty");
uint256 newCatId = ++highestTierIndex;
Expand Down Expand Up @@ -187,6 +187,7 @@ contract Catalyst is
function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(bytes(baseURI).length != 0, "Catalyst: base uri can't be empty");
_setBaseURI(baseURI);
emit BaseURISet(baseURI);
}

/// @notice returns full token URI, including baseURI and token metadata URI
Expand Down Expand Up @@ -223,12 +224,18 @@ contract Catalyst is
return ERC2771HandlerUpgradeable._msgData();
}

/// @dev Sets `baseURI` as the `_baseURI` for all tokens
function _setBaseURI(string memory baseURI) internal virtual override {
super._setBaseURI(baseURI);
emit BaseURISet(baseURI);
}

/// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).
/// @param from address from which tokens are transfered.
/// @param to address to which the token will be transfered.
/// @param id the token type transfered.
/// @param value amount of token transfered.
/// @param data aditional data accompanying the transfer.
/// @param data additional data accompanying the transfer.
function safeTransferFrom(
address from,
address to,
Expand All @@ -245,7 +252,7 @@ contract Catalyst is
/// @param to address to which the token will be transfered.
/// @param ids ids of each token type transfered.
/// @param values amount of each token type transfered.
/// @param data aditional data accompanying the transfer.
/// @param data additional data accompanying the transfer.
function safeBatchTransferFrom(
address from,
address to,
Expand Down Expand Up @@ -286,7 +293,7 @@ contract Catalyst is
return super.supportsInterface(interfaceId);
}

/// @notice This function is used to register Catalyst contract on the Operator Filterer Registry of Opensea.can only be called by admin.
/// @notice This function is used to register Catalyst contract on the Operator Filterer Registry of OpenSea. Can only be called by admin.
/// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.
/// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.
/// @param subscribe bool to signify subscription "true"" or to copy the list "false".
Expand All @@ -298,10 +305,13 @@ contract Catalyst is
_registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);
}

/// @notice sets filter registry address deployed in test
/// @notice sets filter registry address
/// @param registry the address of the registry
function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(registry != address(0), "Catalyst: registry can't be zero address");
operatorFilterRegistry = IOperatorFilterRegistry(registry);
OperatorFiltererUpgradeable._setOperatorFilterRegistry(registry);
emit OperatorRegistrySet(registry);
}

uint256[49] private __gap;
}
31 changes: 30 additions & 1 deletion packages/asset/contracts/interfaces/IAsset.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.18;

/// @title Asset interface
/// @author The Sandbox
interface IAsset {
// AssetData reflects the asset tokenId structure
// Refer to TokenIdUtils.sol
Expand All @@ -17,32 +19,59 @@ interface IAsset {

event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);

// Functions
/// @notice Mint new tokens
/// @dev Only callable by the minter role
/// @param to The address of the recipient
/// @param id The id of the token to mint
/// @param amount The amount of the token to mint
/// @param metadataHash The metadata hash of the token to mint
function mint(
address to,
uint256 id,
uint256 amount,
string memory metadataHash
) external;

/// @notice Mint new tokens with catalyst tier chosen by the creator
/// @dev Only callable by the minter role
/// @param to The address of the recipient
/// @param ids The ids of the tokens to mint
/// @param amounts The amounts of the tokens to mint
/// @param metadataHashes The metadata hashes of the tokens to mint
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
string[] memory metadataHashes
) external;

/// @notice Burn a token from a given account
/// @dev Only the minter role can burn tokens
/// @dev This function was added with token recycling and bridging in mind but may have other use cases
/// @param account The account to burn tokens from
/// @param id The token id to burn
/// @param amount The amount of tokens to burn
function burnFrom(
address account,
uint256 id,
uint256 amount
) external;

/// @notice Burn a batch of tokens from a given account
/// @dev Only the minter role can burn tokens
/// @dev This function was added with token recycling and bridging in mind but may have other use cases
/// @dev The length of the ids and amounts arrays must be the same
/// @param account The account to burn tokens from
/// @param ids An array of token ids to burn
/// @param amounts An array of amounts of tokens to burn
function burnBatchFrom(
address account,
uint256[] memory ids,
uint256[] memory amounts
) external;

/// @notice returns the tokenId associated with provided metadata hash
/// @param metadataHash The metadata hash to get tokenId for
/// @return tokenId the tokenId associated with the metadata hash
function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256);
}
2 changes: 2 additions & 0 deletions packages/asset/contracts/interfaces/IAssetCreate.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.18;

/// @title AssetCreate interface
/// @author The Sandbox
interface IAssetCreate {
event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);
event AssetMinted(
Expand Down
Loading

1 comment on commit f63b04d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage for this commit

96.15%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
packages/asset/contracts
   Asset.sol94.53%89.58%96.43%98.08%116, 207, 312, 312–313, 76
   AssetCreate.sol94.51%83.33%100%100%138, 140, 173, 293, 72
   AssetReveal.sol94.35%86.21%96.55%98.89%143, 147, 181, 376, 416, 424, 441, 75, 98
   AuthSuperValidator.sol90%83.33%100%88.89%51–52
   Catalyst.sol95%91.94%95.45%98.21%125, 127, 140, 152, 224, 80
packages/asset/contracts/interfaces
   IAsset.sol100%100%100%100%
   IAssetCreate.sol100%100%100%100%
   IAssetReveal.sol100%100%100%100%
   ICatalyst.sol100%100%100%100%
   ITokenUtils.sol100%100%100%100%
packages/asset/contracts/libraries
   TokenIdUtils.sol100%100%100%100%
packages/dependency-metatx/contracts
   ERC2771Handler.sol100%100%100%100%
   ERC2771HandlerAbstract.sol100%100%100%100%
   ERC2771HandlerUpgradeable.sol95.45%83.33%100%100%43
packages/dependency-metatx/contracts/test
   ERC2771HandlerTest.sol100%100%100%100%
   ERC2771HandlerUpgradeableTest.sol100%100%100%100%
   MockTrustedForwarder.sol0%0%0%0%15, 18–19, 19, 19–20
packages/dependency-operator-filter/contracts
   OperatorFiltererUpgradeable.sol82.35%85%71.43%83.33%17, 51–52, 61–62, 71, 87
   OperatorFilterSubscription.sol60%50%100%50%19–20
packages/dependency-operator-filter/contracts/interfaces
   IOperatorFilterRegistry.sol100%100%100%100%
packages/dependency-royalty-management/contracts
   MultiRoyaltyDistributor.sol84.06%65%90%92.31%104, 144, 25, 41, 41, 41, 41, 60–61, 97
   RoyaltyDistributor.sol78.95%50%80%90%20, 50, 56
   RoyaltyManager.sol96.39%87.50%100%100%104, 47, 98
   RoyaltySplitter.sol92.08%75%92.31%97.06%117, 157, 185, 218, 65, 72, 83
packages/dependency-royalty-management/contracts/interfaces
   IERC20Approve.sol100%100%100%100%
   IMultiRoyaltyDistributor.sol100%100%100%100%
   IMultiRoyaltyRecipients.sol100%100%100%100%
   IRoyaltyManager.sol100%100%100%100%
   IRoyaltyUGC.sol100%100%100%100%

Please sign in to comment.