Skip to content
This repository has been archived by the owner on Jan 3, 2023. It is now read-only.

Latest commit

 

History

History
459 lines (303 loc) · 9.4 KB

0013.md

File metadata and controls

459 lines (303 loc) · 9.4 KB
  DSP: 0013
  Title: Marketplace v2 contract
  Author: Ignacio Mazzara 
  Status: Final
  Type: Standards
  Created: 2019-04-25

Marketplace v2 contract

Table of Contents

Introduction

Every LAND and Estate in Decentraland can be exchanged for MANA by an mart contract which provides the ability to do a trustless and transparent atomic swap.

Abstract

Digital assets (Non-fungible tokens) can be traded in exchange for MANA to increase the Decentraland economy.

Within this marketplace, new users will be part of the Decentraland ecosystem using their MANA to buy any token which follows the ERC721 Ethereum standard and the Decentraland Composable ERC721 standard.

The Marketplace v2 contract exists within an EVM blockchain (currently Ethereum).

This document describes the structure and the expected behavior and functionality of interacting components provided by the Marketplace v2 contract also known as the Marketplace contract.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 8174 when, and only when, they appear in all capitals, as shown here.

Motivation

With the marketplace v1 accepting only LAND to be traded, the creation of the Estates, the first Composable NFT, and the need of having and play with all the ERC721 tokens inside of Decentraland, made us thinking of creating a marketplace contract accepting every token which follows the ERC721 Ethereum standard and the Decentraland Composable ERC721 standard to be traded in exchange for MANA.

Compatibility

The Marketplace v2 contract is compatible with token which follows the ERC721 Ethereum standard and the MANA token.

Its implementation can be find here.

Terminology

Order: NFT listing. Every order has its unique id generated by the block timestamp, NFT owner, id and the price.

Asset: NFT token which follows the ERC721 Ethereum standard.

Composable Asset: NFT token which is composed by others NFTs. E.g: An Estate is a composable NFT of LANDs.

Legacy NFT: NFT token supported on the marketplace v1.

Account: an Ethereum address.

Design

Contract

This contract is upgradable, ownable and pausable.

It accepts only tokens which follow the ERC721 Ethereum standard for listing and the MANA token for buying.

The MANA contract is set at the contract creation stage.

The contract also needs to be created with a legacyNFTAddress. This address is for the LAND token originally accepted by the marketplace v1 to continue supporting its methods.

The upgradability feature was dropped to a self-destructed contract which means that nobody can upgrade it.

Ownable

The contract has an owner called contract owner which play as an admin. He can transfer its ownership, pause and unpause the contract.

Pausable

The contract can stop accepting, cancelling and executing orders. The pause functionality can be actionable only by the contract owner.

Roles

Contract owner

The account owner of the Marketplace v1 contract.

Specification

Events

OrderCreated

Emitted when an asset is listed for sale.

OrderCreated(
  bytes32 id,
  uint256 assetId,
  address seller,
  address NFTAddress,
  uint256 priceInWei,
  uint256 expiresAt
)

OrderCancelled

Emitted when an asset listing was cancelled

OrderCancelled(
  bytes32 id,
  uint256 assetId,
  address seller,
  address NFTAddress
)

OrderSuccessful

Emitted when an asset was successfully bought.

OrderSuccessful(
  bytes32 id,
  uint256 assetId,
  address seller,
  address NFTAddress,
  uint256 totalPrice,
  address buyer
)

AuctionCreated

Emitted when an asset of the legacy NFT was listed for sale. The OrderCreatead event will be emitted too.

AuctionCreated(
  bytes32 id,
  uint256 assetId,
  address seller,
  uint256 priceInWei,
  uint256 expiresAt
)

AuctionSuccessful

Emitted when an asset of the legacy NFT was successfully bought. The OrderSuccessful event will be emitted too.

AuctionSuccessful(
  bytes32 id,
  uint256 assetId,
  address seller,
  uint256 totalPrice,
  address winner
)

AuctionCancelled

Emitted when an asset of the legacy NFT listing was cancelled. The OrderCancelled event will be emitted too.

AuctionCancelled(bytes32 id, uint256 assetId, address seller)

ChangedPublicationFee

Emitted when the fee for listing was changed

ChangedPublicationFee(uint256 publicationFee)

ChangedOwnerCutPerMillion

Emitted when the fee for selling was changed

ChangedOwnerCutPerMillion(uint256 ownerCut)

ChangeLegacyNFTAddress

Emitted when the legacy NFT address was changed

ChangeLegacyNFTAddress(address legacyNFTAddress)

Pause

Emitted when the contract was paused

Pause

Unpause

Emitted when the contract was unpaused

Unpause

OwnershipTransferred

Emitted when the contract owner was changed

OwnershipTransferred( address previousOwner, address newOwner)

Migrated

Emitted when the contract was migrated.

Migrated(string contractName, string migrationId)

Functions

Listing

createOrder

Listing an asset with a desired price and expiration (Unix time).

createOrder(
  address NFTAddress,
  uint256 assetId,
  uint256 priceInWei,
  uint256 expiresAt
)

LEGACY createOrder

Listing a legacy NFT with a desired price and expiration (Unix time).

createOrder(
  uint256 assetId,
  uint256 priceInWei,
  uint256 expiresAt
)

executeOrder

executeOrder(address NFTAddress, uint256 assetId, uint256 price)

Buy a listing for an asset. The price should match with the listed price and also the buyer should have at least that balance in MANA.

safeExecuteOrder

Buy a listing for a composable asset. The fingerprint and the price should match with the listed ones and also the buyer should have at least that balance in MANA.

safeExecuteOrder(
  address NFTAddress,
  uint256 assetId,
  uint256 price,
  bytes fingerprint
)

LEGACY executeOrder

Buy a listing for a legacy NFT. The price should match with the listed price and also the buyer should have at least that balance in MANA.

executeOrder(uint256 assetId, uint256 price)

cancelOrder

Cancel a NFT listing.

cancelOrder(address NFTAddress, uint256 assetId)

LEGACY cancelOrder

Cancel a legacy NFT listing.

cancelOrder(int256 assetId)

Utils

auctionByAssetId

Get the order by the asset id.

orderByAssetId(address, uint256)

auctionByAssetId

Get a legacy NFT order by the asset id.

auctionByAssetId(uint256)

publicationFeeInWei

Get the publication fee.

publicationFeeInWei()

acceptedToken

Get the accepted token address.

acceptedToken()

paused

Get whether the contract is paused or not.

paused()

ownerCutPerMillion

Get the fee for listing an asset in millions.

ownerCutPerMillion()

owner

Get the contract owner address.

owner()

legacyNFTAddress

Get the legacy NFT address

legacyNFTAddress()

ERC721_Interface

Get the 4 bytes hash of of the ERC721 Ethereum standard interface.

ERC721_Interface()

InterfaceId_ValidateFingerprint

Get the 4 bytes hash for the Decentraland Composable ERC721 standard interface.

InterfaceId_ValidateFingerprint()

Admin

setOwnerCutPerMillion

Set the fee for listing an asset.

setOwnerCutPerMillion(uint256 _ownerCutPerMillion)

setPublicationFee

Set the fee for buying an asset listed

setPublicationFee(uint256 publicationFee)

pause

Pause the contract

pause()

unpause

Unpause contract.

unpause()

destroy

Destroy the contract.

destroy()

transferOwnership

Transfer the ownership of the contract to another account.

transferOwnership(address _newOwner)

setLegacyNFTAddress

Set the legacy NFT address.

setLegacyNFTAddress(address _legacyNFTAddress)

Limitations

This contract only accepts MANA in exchange for the assets listed.

Users need to approve their MANA on contract behalf. Therefore was a potential risk of stealing a lot of MANA if the contract can change its implementation because the contract can move user's MANA.