• This repository has been archived on 01/Sep/2023
  • Stars
    star
    311
  • Rank 134,521 (Top 3 %)
  • Language
    Solidity
  • License
    MIT License
  • Created about 2 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Operator Filter Registry

Introduction

This repository contains a number of tools to help token contracts manage the operators allowed to transfer tokens on behalf of users - including the smart contracts and delegates of marketplaces that do not respect creator earnings.

This is not a foolproof approach - but it makes bypassing creator earnings less liquid and easy at scale.

How it works

Token smart contracts may register themselves (or be registered by their "owner") with the OperatorFilterRegistry. Token contracts or their "owner"s may then curate lists of operators (specific account addresses) and codehashes (smart contracts deployed with the same code) that should not be allowed to transfer tokens on behalf of users.

Creator Earnings Enforcement

OpenSea will enforce creator earnings for smart contracts that make best efforts to filter transfers from operators known to not respect creator earnings.

This repository facilitates that process by providing smart contracts that interface with the registry automatically, including automatically subscribing to OpenSea's list of filtered operators.

When filtering operators, use of this registry is not required, nor is it required for a token contract to "subscribe" to OpenSea's list within this registry. Subscriptions can be changed or removed at any time. Filtered operators and codehashes may likewise be added or removed at any time.

Contract owners may implement their own filtering outside of this registry, or they may use this registry to curate their own lists of filtered operators. However, there are certain contracts that are filtered by the default subscription, and must be filtered in order to be eligible for creator earnings enforcement on OpenSea.

Note on EIP-2981

Implementing EIP-2981 is not sufficient for a token to be eligible for creator earnings on OpenSea.

While sometimes described as "on-chain," EIP-2981 only provides a method to determine what the appropriate creator earnings should be for a sale. EIP-2981 does not provide any mechanism of on-chain enforcement of those earnings.

Filtered addresses

Entries in this list are added according to the following criteria:

  • If the application most commonly used to interface with the contract gives buyers and sellers the ability to bypass creator earnings when a similar transaction for the same item would require creator earnings payment on OpenSea.io
  • If the contract is facilitating the evasion of on-chain creator earnings enforcement measures. For example, the contract uses a wrapper contract to bypass earnings enforcement.
Name Address Network
LooksRare TransferManagerERC721 0xf42aa99F011A1fA7CDA90E5E98b277E306BcA83e Ethereum Mainnet
LooksRare TransferManagerERC1155 0xFED24eC7E22f573c2e08AEF55aA6797Ca2b3A051 Ethereum Mainnet
SudoSwap LSSVMPairEnumerableERC20 0xD42638863462d2F21bb7D4275d7637eE5d5541eB Ethereum Mainnet
SudoSwap LSSVMPairEnumerableETH 0x08CE97807A81896E85841d74FB7E7B065ab3ef05 Ethereum Mainnet
SudoSwap LSSVMPairMissingEnumerableERC20 0x92de3a1511EF22AbCf3526c302159882a4755B22 Ethereum Mainnet
SudoSwap LSSVMPairMissingEnumerableETH 0xCd80C916B1194beB48aBF007D0b79a7238436D56 Ethereum Mainnet
SudoSwap LSSVMPairFactory 0xb16c1342E617A5B6E4b631EB114483FDB289c0A4 Ethereum Mainnet
NFTX NFTXMarketplaceZap 0x0fc584529a2aefa997697fafacba5831fac0c22d Ethereum Mainnet
Looksrare V2 TransferManager 0x000000000060C4Ca14CfC4325359062ace33Fe3D Ethereum Mainnet

Deployments

Usage

Token contracts that wish to manage lists of filtered operators and restrict transfers from them may integrate with the registry easily with tokens using the OperatorFilterer and DefaultOperatorFilterer contracts. These contracts provide modifiers (onlyAllowedOperator and onlyAllowedOperatorApproval) which can be used on the token's transfer methods to restrict transfers from or approvals of filtered operators.

See the ExampleERC721 and ExampleERC1155 contracts for basic implementations that inherit the DefaultOperatorFilterer.

Getting Started with Foundry

This package can be installed into a Foundry project with the following command

forge install ProjectOpenSea/operator-filter-registry

With default remappings provided by forge remappings, the default operator filterer can be imported into your project with the following statement

import "operator-filter-registry/DefaultOperatorFilterer.sol";

See NPM section below for further details.

Getting started with NPM

This package can be found on NPM to integrate with tools like hardhat.

Installing

with npm

npm i operator-filter-registry

with yarn

yarn add operator-filter-registry

Default usage

Add to your smart contract in the import section:

import "operator-filter-registry/src/DefaultOperatorFilterer.sol";

Next extend from DefaultOperatorFilterer

contract MyNft is
  DefaultOperatorFilterer,
  // remaining inheritance here
{

Finally, override the ERC721 transfer and approval methods (modifiers are overridable as needed)

    function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) {
        super.approve(operator, tokenId);
    }

    function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
        public
        override
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId, data);
    }

Smart Contracts

OperatorFilterRegistry

OperatorFilterRegistry lets a smart contract or its EIP-173 Owner register a list of addresses and code hashes to deny when isOperatorBlocked is called.

It also supports "subscriptions," which allow a contract to delegate its operator filtering to another contract. This is useful for contracts that want to allow users to delegate their operator filtering to a trusted third party, who can continuously update the list of filtered operators and code hashes. Subscriptions may be cancelled at any time by the subscriber or its Owner.

updateOperator(address registrant, address operator, bool filtered)

This method will toggle filtering for an operator for a given registrant. If filtered is true, isOperatorAllowed will return false. If filtered is false, isOperatorAllowed will return true. This can filter known addresses.

updateCodeHash(address registrant, bytes32 codeHash, bool filtered)

This method will toggle filtering on code hashes of operators given registrant. If an operator's EXTCODEHASH matches a filtered code hash, isOperatorAllowed will return true. Otherwise, isOperatorAllowed will return false. This can filter smart contract operators with different addresses but the same code.

OperatorFilterer

This smart contract is meant to be inherited by token contracts so they can use the following:

  • onlyAllowedOperator modifier for transferFrom and safeTransferFrom methods.
  • onlyAllowedOperatorApproval modifier for approve and setApprovalForAll methods.

On construction, it takes three parameters:

  • address registry: the address of the OperatorFilterRegistry contract
  • address subscriptionOrRegistrantToCopy: the address of the registrant the contract will either subscribe to, or do a one-time copy of that registrant's filters. If the zero address is provided, no subscription or copies will be made.
  • bool subscribe: if true, subscribes to the previous address if it was not the zero address. If false, copies existing filtered addresses and codeHashes without subscribing to future updates.

Please note that if your token contract does not provide an owner with EIP-173, it must provide administration methods on the contract itself to interact with the registry otherwise the subscription will be locked to the options set during construction.

onlyAllowedOperator(address operator)

This modifier will revert if the operator or its code hash is filtered by the OperatorFilterRegistry contract.

DefaultOperatorFilterer

This smart contract extends OperatorFilterer and automatically configures the token contract that inherits it to subscribe to OpenSea's list of filtered operators and code hashes. This subscription can be updated at any time by the owner by calling updateSubscription on the OperatorFilterRegistry contract.

Please note that if your token contract does not provide an owner with EIP-173, it must provide administration methods on the contract itself to interact with the registry otherwise the subscription will be locked to the options set during construction.

OwnedRegistrant

This Ownable smart contract is meant as a simple utility to enable subscription addresses that can easily be transferred to a new owner for administration. For example: an EOA curates a list of filtered operators and code hashes, and then transfers ownership of the OwnedRegistrant to a multisig wallet.

Validation

When the first token is minted on an NFT smart contract, OpenSea checks if the filtered operators on that network (Ethereum Mainnet, Goerli, Polygon, etc.) are allowed to transfer the token. If they are, OpenSea will mark the collection as ineligible for creator earnings. Otherwise, OpenSea will enforce creator earnings on the collection.

If at a later point, OpenSea detects orders being fulfilled by filtered operators, OpenSea will mark the collection as ineligible for creator earnings going forward.

The included validation test runs the same checks that OpenSea does when first creating a collection page, and can be extended with custom setup for your token contract.

The test can be configured to test against deployed contracts on a network fork with a .env file following the sample.env. You may need to supply a custom [rpc_endpoints] in the foundry.toml file for forking to work properly.

To run only the validation tests, run

forge test --match-contract ValidationTest -vvv

See the Foundry project page for Foundry installation instructions.

Audit

The contracts in this repository have been audited by OpenZeppelin. You may read the final audit report here.

License

MIT Copyright 2022 Ozone Networks, Inc.

More Repositories

1

opensea-js

TypeScript SDK for the OpenSea marketplace
TypeScript
2,278
star
2

seaport

Seaport is a marketplace protocol for safely and efficiently buying and selling NFTs.
Solidity
2,141
star
3

opensea-creatures

Example non-fungible collectible, to demonstrate OpenSea integration
JavaScript
1,167
star
4

opensea-erc1155

Example semi-fungible collectible, to demonstrate OpenSea integration for an ERC-1155 contract
JavaScript
605
star
5

embeddable-nfts

Easily embed OpenSea listings in your website!
TypeScript
329
star
6

seadrop

Smart contracts for primary drops on EVM chains
Solidity
290
star
7

seaport-js

A TypeScript library to interface with the Seaport marketplace.
TypeScript
255
star
8

opensea-whitelabel

Easily whitelabel an OpenSea marketplace for your own website
TypeScript
226
star
9

metadata-api-nodejs

Sample metadata API for crypto collectibles, written in Node.js
JavaScript
193
star
10

stream-js

A TypeScript SDK to receive pushed updates from OpenSea over websocket.
TypeScript
166
star
11

seaport-gossip

A peer-to-peer network for sharing Seaport orders.
TypeScript
125
star
12

metadata-api-python

Simple API for serving ERC721 metadata
Python
117
star
13

nft-tutorial

A very basic NFT tutorial repository for absolute beginners in the world of Web3 and smart contracts
JavaScript
96
star
14

marketplace-benchmarks

A comparison supported features and respective gas overhead for NFT marketplaces
Solidity
70
star
15

meta-transactions

Solidity
49
star
16

seaport-order-validator

Seaport Order Validator provides a simple method for validating and diagnosing Seaport orders
Solidity
48
star
17

shipyard-core

Solidity
48
star
18

seaport-core

Core Seaport smart contracts
Solidity
45
star
19

SIPs

The Seaport Improvement Proposal repository
31
star
20

ethmoji-contracts

Ethmoji smart contracts
JavaScript
22
star
21

seaport.py

Python
21
star
22

seaport-sol

Solidity helpers for working with Seaport on and off-chain using Forge scripts
Solidity
21
star
23

ships-log

An example dapp listing recent auctions and bids on OpenSea, with the ability to buy items or accept offers right from the page.
JavaScript
20
star
24

seaport-1.6

A unified repo containing the core Seaport contracts, types, tools, and tests to facilitate Seaport 1.6 development
Solidity
20
star
25

ethmoji-js

SDK for Ethmoji blockchain avatars
JavaScript
19
star
26

opensea-stream-discord-webhook

A sample repo showing how a developer using the OpenSea Stream API might be able to connect a Discord webhook to send messages whenever new events occur for a collection
TypeScript
18
star
27

0x-fee-wrapper

Solidity
16
star
28

shipyard

Template Repo for OpenSea smart contract development
Solidity
13
star
29

redeemables

EVM smart contracts for redeemables and dynamic traits
Solidity
12
star
30

seaport-types

Standalone structs and interfaces related to Seaport
Solidity
12
star
31

tstorish

Use TSTORE in contracts deployed to multiple chains with varying opcode support
Solidity
11
star
32

ethdenver-workshop

Devcon 5 workshop
JavaScript
10
star
33

seaport-generic-adapter

A proof of concept Seaport app that enables fulfilling non-Seaport listings through Seaport.
Solidity
10
star
34

seaport-deploy

A utility for deploying Seaport to local chains for use in testing.
Solidity
9
star
35

seaport-hooks

A collection of various Seaport Hooks (zone hooks, contract hooks, and item hooks): https://docs.opensea.io/docs/seaport-hooks
5
star
36

ethmoji-js-demo

JavaScript
5
star
37

jellyfish

Build UIs as state machines using Compose.
Kotlin
5
star
38

buy-sell-opensea-sdk-demo

https://docs.opensea.io/docs/buy-sell-nfts
TypeScript
3
star
39

vercel-repros

TypeScript
1
star