• Stars
    star
    161
  • Rank 226,841 (Top 5 %)
  • Language
    TypeScript
  • License
    GNU General Publi...
  • Created over 3 years ago
  • Updated 8 months ago

Reviews

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

Repository Details

A protocol to create, share and exchange universally accessible and valuable media on the internet.

Zora Media Protocol

This repository contains the core contracts that compose the Zora Media Protocol.

The protocol aims to provide a universal value system for media.

Further documentation is available at zora.engineering

Table of Contents

Whitepaper

The whitepaper is available at docs.zora.co

Architecture

This protocol is an extension of the ERC-721 NFT standard, intended to provide a unified pool of liquidity in the form of bids in a market for each NFT. This protocol refers to NFTs as Media.

The protocol's roles and methods interact with the core contracts as follows: Architecture Diagram

The following structs are defined in the contract and used as parameters for some methods:

// Decimal.D256
struct D256 {
  uint256 value;
}

struct Bid {
  // Amount of the currency being bid
  uint256 amount;
  // Address to the ERC20 token being used to bid
  address currency;
  // Address of the bidder
  address bidder;
  // Address of the recipient
  address recipient;
  // % of the next sale to award the previous owner
  Decimal.D256 sellOnShare;
}

struct Ask {
  // Amount of the currency being asked
  uint256 amount;
  // Address to the ERC20 token being asked
  address currency;
  // % of the next sale to award the previous owner
  Decimal.D256 sellOnShare;
}

struct BidShares {
  // % of sale value that goes to the _previous_ owner of the nft
  Decimal.D256 prevOwner;
  // % of sale value that goes to the original creator of the nft
  Decimal.D256 creator;
  // % of sale value that goes to the seller (current owner) of the nft
  Decimal.D256 owner;
}

struct MediaData {
  // A valid URI of the content represented by this token
  string tokenURI;
  // A valid URI of the metadata associated with this token
  string metadataURI;
  // A SHA256 hash of the content pointed to by tokenURI
  bytes32 contentHash;
  // A SHA256 hash of the content pointed to by metadataURI
  bytes32 metadataHash;
}

struct EIP712Signature {
  uint256 deadline;
  uint8 v;
  bytes32 r;
  bytes32 s;
}

Mint

At any time, a creator may mint a new piece of media. When a piece is minted, the new media is transferred to the creator and a market is formed.

Name Type Description
data MediaData The data represented by this media, including SHA256 hashes for future integrity checks
bidShares BidShares The percentage of bid fees that should be perpetually rewarded to the creator.

Mint process flow diagram

Set Bid

Anyone may place a bid on a minted token. By placing a bid, the bidder deposits the currency of their choosing into the market contract. Any valid ERC-20 currencies can be used to bid. Note that we strongly recommend that bidders do not bid using a currency that can be rebased, such as AMPL, YAM, or BASED, as funds can become locked in the Market if the token is rebased.

Name Type Description
tokenId uint256 The tokenID for the media being bid on
bid Bid The bid to be placed

Set Bid process flow diagram

Remove Bid

Once a bid has been set by a bidder, it can be removed. In order to remove a bid from a piece of media, the bidder simply specifies the piece of media that they wish to remove their bid from. Note from the process flow diagram above for setting a bid that only one bid can be set a time per bidder per piece of media.

Name Type Description
tokenId uint256 The tokenID for the media who's bid is being removed

Remove Bid process flow diagram

Transfer

Any media owner is able to transfer their media to an address of their choosing. This does not alter the market for the media, except to remove the Ask on the piece, if it is present. Its implementation from the standard ERC721 standard is unchanged in this protocol.

Burn

This protocol allows for media to be burned, if and only if the owner of the media is also the creator. When burned, the tokenURI and metadataURI of the media are not removed. This means that even though the market becomes inactive, the media is still viewable. Effectively, the media becomes read-only. Any bids that were placed on a piece prior to it being burned can still be removed.

Name Type Description
tokenId uint256 The tokenID for the media to burn

Burn process flow diagram

Set Ask

At any time, an owner may set an Ask on their media. The ask serves to automatically fulfill a bid if it satisfies the parameters of the ask. This allows collectors to optionally buy a piece outright, without waiting for the owner to explicitly accept their bid.

Name Type Description
tokenId uint256 The tokenID for the media
ask Ask The ask to be set

Set Ask process flow diagram

Accept Bid

When an owner sees a satisfactory bid, they can accept it and transfer the ownership of the piece to the bidder's recipient. The bid's funds are split according to the percentages defined in the piece's bid shares. Note that bids can have a sell-on fee. This fee is to entitle the seller to a piece of the next sale of the media. For example, suppose someone owns a piece with a limited means of promoting it. In this case, it may be favorable to accept a bid from a highly regarded platform for a lower initial capital, but high potential resale fee. Since the sell-on fee can be easily avoided by bidders with ill intent, it's suggested that owners only accept sell-on fee offers from reputable buyers.

Name Type Description
tokenId uint256 The tokenID for the media
bid Bid The bid to accept

Accept Bid process flow diagram

Approve

At any time, the owner of a piece of media is able to approve another address to act on its behalf. This implementation is unchanged from the ERC-721 standard. However, approved addresses are now also able to accept bids, set asks, update URIs, and burn media (provided the owner is the creator, as above).

Update Token and Media URI

Although this protocol is designed to maintain perpetual markets for media, data availability of that media is considered out of scope. However, in the event that the URIs that point to the data must be changed, this protocol offers the ability to update them. Recall that when minting tokens, sha256 hashes of the content and metadata are provided for integrity checks. As a result, anyone is able to check the integrity of the media if the URIs change.

This protocol deviates from the ERC-721 in that the tokenURI does not point to a valid ERC721 Metadata JSON Schema as defined in the EIP. In order to support integrity checks when updating the tokenURIs, the content and metadata of a piece of media are split into tokenURI and metadataURI, respectively. This split effectively allows for the reconfiguration of the URIs of both the content and metadata, while preserving integrity checks.

Metadata JSON schema

In order to enable anyone to use this protocol as they see fit, there is no single metadata JSON schema that is used for this protocol. However, it is strongly recommended that developers submit a valid JSON schema to the Media Metadata Schemas Repository to allow anyone to support custom metadata. The only required key of the JSON metadata is version, which is a string in the format of <name-calVersion> (e.g. zora-20210101). This key can be used by implementing platforms to determine which metadata schemas to support.

Permit

In order to provide support for third parties to interact with this protocol on a user's behalf, the EIP-712 standard for signing typed data structures is supported. The protocol offers a permit method loosely based off of EIP-2612, with some adjustments made to support NFTs rather than ERC-20 currencies. The Permit EIP-712 data structure is as follows:

{
  Permit: [
    { name: 'spender', type: 'address' },
    { name: 'tokenId', type: 'uint256' },
    { name: 'nonce', type: 'uint256' },
    { name: 'deadline', type: 'uint256' },
  ];
}

If the permit is applied, the specified spender is set as approved for the signer. Note that the spender will stay approved until the approval is revoked.

Mint With Signature

If the media has yet to be minted yet, creators are able to permit a third party to mint on their behalf by signing a MintWithSig object. The structure is as follows:

{
  MintWithSig: [
    { name: 'tokenURI', type: 'string' },
    { name: 'metadataURI', type: 'string' },
    { name: 'creatorShare', type: 'uint256' },
    { name: 'nonce', type: 'uint256' },
    { name: 'deadline', type: 'uint256' },
  ];
}

Local Development

The following assumes node >= 12

Install Dependencies

yarn

Compile Contracts

yarn build

Start a Local Blockchain

yarn chain

Run Tests

yarn test

More Repositories

1

v3

Solidity
367
star
2

zora-721-contracts

Zora drops contracts (powers create.zora.co)
Solidity
189
star
3

nft-editions

Contracts to lazy-mint editioned ERC721s
Solidity
164
star
4

auction-house

TypeScript
154
star
5

nft-hooks

NFT Data Fetching Hooks with Zora contract data
TypeScript
135
star
6

create-auction-house

Starter repo for creating your own auction house with Zora's protocol
TypeScript
121
star
7

zdk

TypeScript
107
star
8

zorb

Zorb zelated zings
TypeScript
107
star
9

zora-docs

JavaScript
105
star
10

nouns-protocol

Solidity
104
star
11

offchain

NFT Metadata made easy
Python
103
star
12

nft-components

NFT Rendering Components
TypeScript
98
star
13

nouns-builder

Nouns Builder
TypeScript
83
star
14

zora-protocol

Monorepo for Zora Protocol (contracts & sdks)
Solidity
77
star
15

mint-page-template

TypeScript
71
star
16

nft-metadata

generic nft metadata parsers
TypeScript
65
star
17

faucets

TypeScript
57
star
18

nouns-marketplace

⌐◨-◨
TypeScript
49
star
19

foundry-script-examples

Solidity
44
star
20

doge-nft

DOGE NFT
SCSS
32
star
21

media-metadata-schemas

A repository of known JSON metadata schemas for the Zora media protocol.
TypeScript
29
star
22

themis

The legal terms of service for people's tokenized work
29
star
23

zora-v1-subgraph

TypeScript
27
star
24

zora-token-factory-deprecated-

A token factory that enables any person or community to tokenize any good or endeavour.
JavaScript
21
star
25

nft-cli

NFT CLI library
TypeScript
17
star
26

protocol-rewards

Solidity
16
star
27

nouns-builder-bot

TypeScript
15
star
28

recovery-protocol

Solidity
15
star
29

simple-wallet-provider

Simple Wallet Provider
TypeScript
15
star
30

smol-safe

smol safe ui
TypeScript
15
star
31

chains-cli

Cli for chain configuration
TypeScript
14
star
32

zora-drops-extensions

Extensions for ZORA Drops
Solidity
11
star
33

nouns-ar-glasses-ios

Nouns AR Glasses for iOS
Swift
11
star
34

mintpool

A mempool of things you can bring onchain
Rust
10
star
35

nouns-connect

Connect your Nouns DAOs to DApps
TypeScript
10
star
36

thegrandexchange

welp here goes nothing
TypeScript
9
star
37

json-extension-registry

Store arbitrary JSON data associated with a contract
Solidity
8
star
38

zorb-zenerator

JavaScript
8
star
39

zora-drop-frontend

Frontend template iteration for drop site using Zora drops contract factory.
JavaScript
7
star
40

rent-a-vote

Solidity
7
star
41

cryptomedia

What is Cryptomedia?
HTML
6
star
42

zora-crypto-list

A list of resources to help get started in crypto.
6
star
43

rug-house

Rug Store Auction House!
TypeScript
6
star
44

cli

TypeScript
5
star
45

hollyplus-minting-contract

Simple royalty-enabled IPFS minting contract for holly plus
TypeScript
5
star
46

manage-auction-hooks

Hooks to manage auction state for auction houses, integrates with simple-wallet-hooks
TypeScript
4
star
47

first-lol

TypeScript
3
star
48

mad-realities-auction

TypeScript
3
star
49

matthew-ball-minting-contract

On-chain metadata with contentURI implementation for Matthew Ball's Metaverse Essays
HTML
2
star
50

zora-zine-reader

POC for zora zine reader
TypeScript
1
star
51

uniswap-v2-interface

TypeScript
1
star
52

zora-creator-subgraph

TypeScript
1
star
53

frontend-exercise-one

ZORA Frontend Exercise #1
TypeScript
1
star