Transient Labs BlockList

BlockList is a smart contract utility that can be utilized to block approvals of marketplaces that creators don't want their work trading on.

1. Problem Statement

It's a race to zero in terms of marketplace fees, but in an effort to keep cash flow, some marketplaces have decided forego creator feeds. This hurts creators an incredible amount and we believe that creators should have the option to block having their art listed on these platforms.

2. Our Solution

This is why we created BlockList. The BlockList.sol contract can be inherited by nft contracts and the modifier notBlocked(address) can be used on setApprovalForAll and approve functions in ERC-721 and/or ERC-1155 contracts. We have included a sample implementation of both in this repo.

Theoretically, this modifier could be applied to other functions, but we HIGHLY advise against this. Applying this logic to transfer functions introduces slight vulnerabilties that should be avoided.

To implement BlockList, simply inherit BlockList.sol.

3. Why Not An Allowlist Method Instead?

To keep composability with new standards and reduced interaction needed in the future, BlockList is implemented as a blocker rather than an allower. We welcome feedback on this.

Deployments

See https://docs.transientlabs.xyz/blocklist/implementation for the latest deployments

Usage

When cloning this repo, the proper way to install or update the submodules installed with foundry is to run make remove && make install or make update.

Other methods of installing, such as forge install or forge update are not guaranteed to install the proper modules and you run a risk of installing modules with breaking changes.

Disclaimer

We have verified with OpenSea engineers that BlockList is fully compatible with their royalties enforcement system, as of 11/7/2022.

This codebase is provided on an "as is" and "as available" basis.

We do not give any warranties and will not be liable for any loss incurred through any use of this codebase.

License

This code is copyright Transient Labs, Inc 2023 and is licensed under the MIT license.

BlockAllRegistry

Git Source

Inherits: IBlockListRegistry

Author: transientlabs.xyz

BlockList that blocks all approvals and can be used as a semi-soulbound token

Functions

getBlockListStatus

Function to get blocklist status with True meaning that the operator is blocked

function getBlockListStatus(address) external pure override returns (bool);

Parameters

NameTypeDescription
<none>address

setBlockListStatus

Function to set the block list status for multiple operators

Must be called by the blockList owner

function setBlockListStatus(address[] calldata, bool) external pure override;

Parameters

NameTypeDescription
<none>address[]
<none>bool

clearBlockList

Function to clear the block list status

Must be called by the blockList owner

function clearBlockList() external pure override;

BlockListRegistry

Git Source

Inherits: IBlockListRegistry, OwnableAccessControlUpgradeable, ERC165Upgradeable

Author: transientlabs.xyz

Registry that can be used to block approvals from non-royalty paying marketplaces

State Variables

BLOCK_LIST_ADMIN_ROLE

bytes32 public constant BLOCK_LIST_ADMIN_ROLE = keccak256("BLOCK_LIST_ADMIN_ROLE");

_c

uint256 private _c;

_blockList

mapping(uint256 => mapping(address => bool)) private _blockList;

Functions

constructor

constructor(bool disable);

Parameters

NameTypeDescription
disableboolDisable the initalizer on deployment

initialize

Function that can be called once to initialize the registry

function initialize(address newOwner, address[] memory initBlockList) external initializer;

Parameters

NameTypeDescription
newOwneraddressThe initial owner of this contract
initBlockListaddress[]Initial list of addresses to add to the blocklist

clearBlockList

Function to clear the block list status

Must be called by the blockList owner or blocklist admin

function clearBlockList() external onlyRoleOrOwner(BLOCK_LIST_ADMIN_ROLE);

getBlockListStatus

Function to get blocklist status with True meaning that the operator is blocked

function getBlockListStatus(address operator) public view returns (bool);

Parameters

NameTypeDescription
operatoraddressThe operator in question to check against the blocklist

supportsInterface

function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool);

setBlockListStatus

Function to set the block list status for multiple operators

Must be called by the blockList owner

function setBlockListStatus(address[] calldata operators, bool status)
    external
    onlyRoleOrOwner(BLOCK_LIST_ADMIN_ROLE);

Parameters

NameTypeDescription
operatorsaddress[]An address array of operators to set a status for
statusboolThe status to set for all operators

_getBlockListStatus

Internal function to get blockList status

function _getBlockListStatus(address operator) internal view returns (bool);

Parameters

NameTypeDescription
operatoraddressThe address for which to get the BlockList status

_setBlockListStatus

Internal function to set blockList status for one operator

function _setBlockListStatus(address operator, bool status) internal;

Parameters

NameTypeDescription
operatoraddressAddress to set the status for
statusboolTrue means add to the BlockList

IBlockListRegistry

Git Source

Author: transientlabs.xyz

Interface for the BlockListRegistry Contract

Functions

getBlockListStatus

Function to get blocklist status with True meaning that the operator is blocked

function getBlockListStatus(address operator) external view returns (bool);

Parameters

NameTypeDescription
operatoraddressThe operator in question to check against the blocklist

setBlockListStatus

Function to set the block list status for multiple operators

Must be called by the blockList owner

function setBlockListStatus(address[] calldata operators, bool status) external;

Parameters

NameTypeDescription
operatorsaddress[]An address array of operators to set a status for
statusboolThe status to set for all operators

clearBlockList

Function to clear the block list status

Must be called by the blockList owner

function clearBlockList() external;

Events

BlockListStatusChange

event BlockListStatusChange(address indexed user, address indexed operator, bool indexed status);

BlockListCleared

event BlockListCleared(address indexed user);