Skip to content

Commit

Permalink
Merge branch 'asset-l2-integration' of https://github.com/thesandboxg…
Browse files Browse the repository at this point in the history
…ame/sandbox-smart-contracts into asset-audit-n-05
  • Loading branch information
wojciech-turek committed Sep 15, 2023
2 parents d003b1d + fc06649 commit 68d046e
Show file tree
Hide file tree
Showing 52 changed files with 1,151 additions and 764 deletions.
102 changes: 47 additions & 55 deletions packages/asset/contracts/Asset.sol
Original file line number Diff line number Diff line change
@@ -1,35 +1,23 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.18;

import {
AccessControlUpgradeable,
ContextUpgradeable
} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import {
ERC1155BurnableUpgradeable,
ERC1155Upgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol";
import {
ERC1155SupplyUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol";
import {
ERC1155URIStorageUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol";
import {AccessControlUpgradeable, ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import {ERC1155BurnableUpgradeable, ERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol";
import {ERC1155SupplyUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol";
import {ERC1155URIStorageUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {
ERC2771HandlerUpgradeable
} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol";
import {
MultiRoyaltyDistributor
} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol";
import {
OperatorFiltererUpgradeable,
IOperatorFilterRegistry
} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol";
import {ERC2771HandlerUpgradeable} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol";
import {MultiRoyaltyDistributor} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol";
import {OperatorFiltererUpgradeable, IOperatorFilterRegistry} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol";
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 +44,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,12 +72,8 @@ 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
function mint(
address to,
uint256 id,
uint256 amount,
string memory metadataHash
) external onlyRole(MINTER_ROLE) {
/// @param metadataHash The metadata hash of the token to mint
function mint(address to, uint256 id, uint256 amount, string memory metadataHash) external onlyRole(MINTER_ROLE) {
_setMetadataHash(id, metadataHash);
_mint(to, id, amount, "");
address creator = id.getCreatorAddress();
Expand All @@ -95,6 +85,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 All @@ -119,11 +110,7 @@ contract Asset is
/// @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 onlyRole(BURNER_ROLE) {
function burnFrom(address account, uint256 id, uint256 amount) external onlyRole(BURNER_ROLE) {
_burn(account, id, amount);
}

Expand Down Expand Up @@ -159,19 +146,22 @@ contract Asset is
/// @notice returns full token URI, including baseURI and token metadata URI
/// @param tokenId The token id to get URI for
/// @return tokenURI the URI of the token
function uri(uint256 tokenId)
public
view
override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)
returns (string memory tokenURI)
{
function uri(
uint256 tokenId
) public view override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable) returns (string memory tokenURI) {
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 tokenId) {
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 All @@ -192,7 +182,9 @@ contract Asset is
/// @notice Query if a contract implements interface `id`.
/// @param id the interface identifier, as specified in ERC-165.
/// @return supported `true` if the contract implements `id`.
function supportsInterface(bytes4 id)
function supportsInterface(
bytes4 id
)
public
view
virtual
Expand Down Expand Up @@ -253,12 +245,10 @@ contract Asset is
/// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.
/// @param operator address which will be granted rights to transfer all tokens of the caller.
/// @param approved whether to approve or revoke
function setApprovalForAll(address operator, bool approved)
public
virtual
override
onlyAllowedOperatorApproval(operator)
{
function setApprovalForAll(
address operator,
bool approved
) public virtual override onlyAllowedOperatorApproval(operator) {
_setApprovalForAll(_msgSender(), operator, approved);
}

Expand Down Expand Up @@ -336,22 +326,24 @@ contract Asset is
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.
/// @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.
/// @param subscribe bool to signify subscription "true"" or to copy the list "false".
function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
function registerAndSubscribe(
address subscriptionOrRegistrantToCopy,
bool subscribe
) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(subscriptionOrRegistrantToCopy != address(0), "Asset: subscription can't be zero address");
_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;
}
Loading

1 comment on commit 68d046e

@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%178, 283, 283–284, 59, 94
   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.