Skip to content

Commit

Permalink
Merge pull request #1120 from thesandboxgame/catalyst-audit/N-04-cont…
Browse files Browse the repository at this point in the history
…ract-should-be-abstract

Catalyst audit: N-04 Contract Should Be Abstract
  • Loading branch information
rishabh0x00 authored Sep 11, 2023
2 parents 9d058bf + e3f416e commit 50a12fe
Show file tree
Hide file tree
Showing 16 changed files with 144 additions and 119 deletions.
2 changes: 1 addition & 1 deletion packages/asset/contracts/Asset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ 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".
Expand Down
10 changes: 5 additions & 5 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 @@ -235,7 +235,7 @@ contract Catalyst is
/// @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 @@ -252,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 @@ -293,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 Down
8 changes: 4 additions & 4 deletions packages/asset/docs/Asset.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,15 @@ Sets a new trusted forwarder for meta-transactions.
Parameters:

- `trustedForwarder` - The new trusted forwarder.

### setTokenRoyalties

```solidity
function setTokenRoyalties(
uint256 tokenId,
address payable recipient,
address creator
) external override onlyRole(DEFAULT_ADMIN_ROLE)
) external override onlyRole(DEFAULT_ADMIN_ROLE)
```

Sets token royalty i.e. the creator splitter address as EIP2981 royalty recipient. deploys a splitter if there is none deployed for a creator. Only admin can call it.
Expand Down Expand Up @@ -254,7 +255,6 @@ Parameters:

- `tokenId` - the id of the token.


### isBridged

```solidity
Expand All @@ -275,7 +275,7 @@ function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subsc
onlyRole(DEFAULT_ADMIN_ROLE)
```

Used to register and subscribe on the operator filter registry of Opensea
Used to register and subscribe on the operator filter registry of OpenSea

Parameters:

Expand All @@ -286,7 +286,7 @@ Parameters:

```solidity
function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE)
```fu
```

Used to the address of the operator filter registry

Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
# OperatorFilterRegistry
Opensea in an attempt to regularize market places and creator earnings deployed a registry(https://github.com/ProjectOpenSea/operator-filter-registry) and asked NFT token contract to add filter logic(https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterer.sol).
# OperatorFilterRegistry

These filter has two modifier
1st : onlyAllowedOperator
OpenSea in an attempt to regularize market places and creator earnings deployed a registry(https://github.com/ProjectOpenSea/operator-filter-registry) and asked NFT token contract to add filter logic(https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterer.sol).

These filter has two modifier
1st : onlyAllowedOperator
2nd : onlyAllowedOperatorApproval

These modifiers are added to to the transfer functions(onlyAllowedOperator) and approval function(onlyAllowedOperatorApproval) such that the when not an owner tried to transfer a Token(ex: Marketplace) or owner approves an operator(ex : Marketplace) they would be filtered on the OperatorFilterRegistry.
These modifiers are added to to the transfer functions(onlyAllowedOperator) and approval function(onlyAllowedOperatorApproval) such that the when not an owner tried to transfer a Token(ex: Marketplace) or owner approves an operator(ex : Marketplace) they would be filtered on the OperatorFilterRegistry.

If the operator or the token transfer is not approved by the registry the transaction would be reverted.

On OperatorFilterRegistry a contract owner or the contract can register and maintain there own blacklist or subscribe to other blacklists but that blacklist should contain the default marketplaces blacklisted by Opensea.
On OperatorFilterRegistry a contract owner or the contract can register and maintain there own blacklist or subscribe to other blacklists but that blacklist should contain the default marketplaces blacklisted by OpenSea.

# OperatorFiltererRegistrant
# OperatorFiltererRegistrant

The OperatorFiltererRegistrant contract is made to be registered on the OperatorFilterRegistry and copy the default blacklist of the openSea. This contract would then be subscribed by the contract such as AssetERC721 and AssetERC1155.
The OperatorFiltererRegistrant contract is made to be registered on the OperatorFilterRegistry and copy the default blacklist of the OpenSea. This contract would then be subscribed by the contract such as AssetERC721 and AssetERC1155.

The OperatorFiltererRegistrant would be the subscription for our token contracts on a layer(layer-1 : Ethereum , layer-2: Polygon), such that when a address is added or removed from OperatorFiltererRegistrant's blacklist it would be come in affect for each contact which subscribe to the OperatorFiltererRegistrant's blacklist.

# Intended usage

The OperatorFiltererRegistrant is so that sandbox will have a common blacklist that would be utilized by every Token contract on a layer. This would create a single list that would be subscribed by each contract to provide uniformity to which market places sandbox wants to blacklist. This would also provide a focal point to remove and add market places such that it would be applicable to every contract that subscribe to it.

# Implementation
# Implementation

We didn't use the npm package as its solidity pragma(solidity version) doesn't match the one we have for our Asset contracts and updating our solidity version for Assets would have been to time consuming.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

/// @title OperatorFilterSubription
/// @author The Sandbox
/// @notice This contract is meant to register and copy the default subscription of the OpenSea for the operator filter and our Token contract are supposed to subscribe to this contract on openSea operator filter registry
/// @notice This contract is meant to register and copy the default subscription of the OpenSea for the operator filter and our Token contract are supposed to subscribe to this contract on OpenSea operator filter registry
contract OperatorFilterSubscription is Ownable {
address public constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);
address public constant DEFAULT_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

// solhint-disable-next-line const-name-snakecase
IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

constructor() Ownable() {
// Subscribe and copy the entries of the Default subscription list of open sea.
// Subscribe and copy the entries of the Default subscription list of OpenSea.
if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), DEFAULT_SUBSCRIPTION);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {IOperatorFilterRegistry} from "./interfaces/IOperatorFilterRegistry.sol"
import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";

///@title OperatorFiltererUpgradeable
///@author The SandBox
///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract
///@author The Sandbox
///@notice This contract would subscribe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's address could be set using a setter which could be implemented in inheriting contract
abstract contract OperatorFiltererUpgradeable is Initializable, ContextUpgradeable {
event OperatorFilterRegistrySet(address indexed registry);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pragma solidity ^0.8.0;
interface IOperatorFilterRegistry {
///@notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
/// true if supplied registrant address is not registered.
function isOperatorAllowed(address registrant, address operator) external view returns (bool);
function isOperatorAllowed(address registrant, address operator) external view returns (bool isAllowed);

///@notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
function register(address registrant) external;
Expand Down Expand Up @@ -66,46 +66,44 @@ interface IOperatorFilterRegistry {

///@notice Get the set of addresses subscribed to a given registrant.
/// Note that order is not guaranteed as updates are made.

function subscribers(address registrant) external returns (address[] memory);
function subscribers(address registrant) external returns (address[] memory subscribersList);

///@notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
/// Note that order is not guaranteed as updates are made.
function subscriberAt(address registrant, uint256 index) external returns (address);
function subscriberAt(address registrant, uint256 index) external returns (address subscriberAddress);

///@notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.

function copyEntriesOf(address registrant, address registrantToCopy) external;

///@notice Returns true if operator is filtered by a given address or its subscription.
function isOperatorFiltered(address registrant, address operator) external returns (bool);
function isOperatorFiltered(address registrant, address operator) external returns (bool isFiltered);

///@notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool isFiltered);

///@notice Returns true if a codeHash is filtered by a given address or its subscription.
function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool isFiltered);

///@notice Returns a list of filtered operators for a given address or its subscription.
function filteredOperators(address addr) external returns (address[] memory);
function filteredOperators(address addr) external returns (address[] memory operatorList);

///@notice Returns the set of filtered codeHashes for a given address or its subscription.
/// Note that order is not guaranteed as updates are made.
function filteredCodeHashes(address addr) external returns (bytes32[] memory);
function filteredCodeHashes(address addr) external returns (bytes32[] memory codeHashList);

///@notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
/// its subscription.
/// Note that order is not guaranteed as updates are made.
function filteredOperatorAt(address registrant, uint256 index) external returns (address);
function filteredOperatorAt(address registrant, uint256 index) external returns (address operator);

///@notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
/// its subscription.
/// Note that order is not guaranteed as updates are made.
function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32 codeHash);

///@notice Returns true if an address has registered
function isRegistered(address addr) external returns (bool);
function isRegistered(address addr) external returns (bool registered);

///@dev Convenience method to compute the code hash of an arbitrary contract
function codeHashOf(address addr) external returns (bytes32);
function codeHashOf(address addr) external returns (bytes32 codeHash);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {

/**
* @title MockOperatorFilterRegistry
* @notice Made based on the OperatorFilterRegistry of openSea at https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterRegistry.sol
* @notice Made based on the OperatorFilterRegistry of OpenSea at https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterRegistry.sol
* @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be
* * restricted according to the isOperatorAllowed function.
*/
Expand Down
Loading

1 comment on commit 50a12fe

@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.34%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
packages/asset/contracts
   Asset.sol94.53%89.58%96.43%98.08%103, 188, 293, 293–294, 65
   AssetCreate.sol94.51%83.33%100%100%130, 132, 165, 281, 68
   AssetReveal.sol94.35%86.21%96.55%98.89%143, 147, 181, 376, 416, 424, 441, 75, 98
   AuthSuperValidator.sol100%100%100%100%
   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.