Deck ERC721
The ERC721 Deck contract allows for the wrapping of ERC721s as Items, and for the burning of Deck-items ERC721s to retrieve the original tokens.
Wrap
Before wrapping an ERC721 token as a Deck Item, make sure it is a standard ERC721. To be standard, it must:
integrate the standard IERC721 interface
have 0 decimals
have a
transferFrom/safeTransferFrom
function that allows for it to be wrapped as a Deck Itemhave a
transferFrom/safeTransferFrom/transfer
function that allows it to be retrieved by wrapping a Deck Item
An ERC721 can be wrapped in two ways:
By using the
mintItems
function (only for ERC721s that have atransferFrom
function)By using the
safeTransferFrom
function to send the token to the ERC721 Deck Wrapper contract, which implementsonERC721Received
.
When wrapped, all ERC721s of the same token address generate the same shared Deck Item id. So, for example, if you wrap two Bored Apes, 2e18 Bored Ape Deck Items are minted, and they share the same Deck Item id.
mintItems
This function has two inputs:
struct
CreateItem
-> data for wrapping the ERC721bool[]
reserveArrays
-> boolean value that expresses whether the wrap is to be reserved (true) or unreserved (false). More on this below.
The lengths of CreateItem
and reserveArrays
must be the same; each CreateItem
struct must correspond to its sequentially equivalent value in reserveArrays
.
For each ERC721 being wrapped, a CreateItem
struct must be passed as follows:
struct
Header
-> composed ofaddress
host
,string
name
,string
symbol
andstring
uri
. Pass this as empty; these parameters are automatically populated by the contract. See here for more info.bytes32
collection
-> encoded ERC721 address of the token being wrapped.uint256
id
-> id of the original ERC721 token being wrapped.address[]
accounts
-> receiver address(es) of the Deck Item. Pass asaddress(0)
to set asmsg.sender
, or pass as any other address(es).uint256[]
amounts
-> 1e18 (i.e. 100000000000000000000000000).
Regarding accounts
and amounts
, 1e18 can be split to multiple receivers. The sum must be 1e18, and the accounts
array and amounts
lengths must be equal; each accounts
value must correspond to its sequentially equivalent value in amounts
.
Example
2 Bored Apes are wrapped as Deck Items; the first reserved, the second unreserved.
CreateItem1
Header -> - host:
0x00..
, - name: " ", symbol: " ", uri: " "collection -> 0x000000000000000000000000bc4ca0eda7647a8ab7c2061c2e118a18a936f13d
id -> 1630
accounts -> 0x998093DF3d61dDDae8F4a84e02e12c78b3751cC4
amounts -> 100000000000000000000000000
CreateItem2:
Header -> - host:
0x00..
, - name: " ", symbol: " ", uri: " "collection -> 0x000000000000000000000000bc4ca0eda7647a8ab7c2061c2e118a18a936f13d
id -> 6724
accounts -> 0x82465CB46506563f66285f18da7adD332e813A42
amounts -> 100000000000000000000000000
reserveArray: [true, false]
Using the mintItems
function, multiple ERC721s of different token addresses can be wrapped in a single transaction by passing multiple CreateItem
structs at once.
The mintItems
function returns the created itemIds
.
onERC721Received
onERC721Received
An ERC721 can also be wrapped by using the safeTransferFrom
function to send it to the ERC721 Deck Wrapper contract, which calls the onERC721Received
function.
The data
parameter of safeTransferFrom
must contain the following encoded parameters:
Uint256[] values
-> represents the amount of Deck Items (in 18 decimals) to send to each receiver address.Address[] receivers
-> addresses that will receive the Deck Item.
The lengths of values[]
and receivers[]
must be the same; each value in values[]
must correspond to its sequentially equivalent value in receivers[]
.
Bool reserve
-> boolean value that expresses whether the token wrap must be reserved (true) or unreserved (false). More on this below.
values
and receivers
work in the same way as the amounts
and accounts
parameters of the mintItems
function.
Example:
1 Gods Unchained card (id 81046035) is sent to be wrapped as a Deck Item with a reservation to the ERC721 Deck Wrapper contract, using
safeTransferFrom
with the following encodeddata
:
Uint256[] values
-> 100000000000000000000000000
Address[] receivers
-> 0x82465CB46506563f66285f18da7adD332e813A42
Bool reserve
-> true
Reserve
When an ERC721 is wrapped as a Deck Item with a reservation, only the address that wrapped it (i.e. the msg.sender
of the mintItems
/safeTransferFrom
function) can unwrap the Deck Item and retrieve it for the following 10 days (in blocks).
A reservation is for a single ERC721 token.
Each reservation (ReserveData
) corresponds to a struct:
address
unwrapper
-> msg.sender of themintItems
/safeTransferFrom
function.uint256
timeout
-> blocks for which the token is reserved. Equal toblock.number + reserveTimeInBlocks
, wherereserveTimeInBlocks
is the number of blocks that are estimated to correspond to 10 days.
If, at any time during the reservation period, the unwrapper
address transfers the Deck Item to another account, that account will be unable to unwrap it until the end of the 10 day reservation period, at which point it becomes unreserved and can be unwrapped by anyone.
Unlock Reservation
A reservation can be ended without having to unwrap the token, by using the unlockReserves
function:
address[]
tokenAddress
-> address of the original ERC721 to unlock.uint256[]
tokenIds
-> id of the original ERC721 to unlock.
unlockReserves
can be used to unlock multiple reservations at once.
Unwrap
The unwrapping of Deck Items to retrieve the wrapped ERC721s can be done either in single mode, by using the burn
function, or in batch mode, by using the burnBatch
function.
These functions can be called by the Deck Item holder or by an approved operator address.
Burn
address
account
-> address of the Deck Item holder.uint256
itemId
-> id of the Deck Item to burn.uint256
amount
-> amount of the Deck Item to burn.bytes
data
-> data in bytes format that must contain the following encoded parameters:
- address
tokenAddress
-> token address of the wrapped ERC721.
- uint256
tokenId
-> id of the wrapped ERC721.
- address
receiver
-> address that will receive the wrapped ERC721. Pass as address(0)
to set as msg.sender
, or pass as another address.
- bytes
payload
-> eventual optional data to perform a safeTransferFrom
.
- bool
safe
-> boolean parameter to perform either a safeTransferFrom
(true) or a transferFrom
(false).
- bool
withData
-> boolean parameter to perform a safeTransferFrom
either with data (true) or without data (false). In the first case, the payload
is executed as data
.
Example:
1 (in 18 decimals) Bored Ape Deck Item is burned to retrieve Bored Ape 1630.
account
-> 0x998093DF3d61dDDae8F4a84e02e12c78b3751cC4
itemId
-> id of the Bored Ape Deck Item; for example, 553791398095120659341456634
amount
-> 100000000000000000000000000
data
->data = web3.eth.abi.encodeParameters( ["address", "uint256", "address", "bytes", "bool", "bool"], ["0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d", "1630", "0x998093DF3d61dDDae8F4a84e02e12c78b3751cC4", "0x", false, false] );
burnBatch
Using burnBatch
, you can unwrap multiple Deck Items (even if they are of different Decks) at once. burnBatch
can be called by the Deck Item holder or by an approved operator address.
The parameters are the same as those of the burn function, but with the following differences:
uint256[]
itemId
anduint256[]
amount
-> arrays of values, allowing you to unwrap multiple tokens at once.bytes
data
->thedata
parameter in bytes format is an encoded value that represents abytes[]
(one for each Item involved in the operation) containing the six parameters explained above in the burn section (tokenAddress, tokenId, receiver, payload, safe and withData).
Deck Items With a Total Supply <=1
Unwrap
If the total supply of a Deck Item ranges from 0.51 to 1 (in 18 decimals), the ERC721 can be unwrapped by burning an amount of Deck Items between 0.51 and 1 in 18 decimals.
This is contrast to the typical situation where the total supply >1, in which case 1e18 Deck Items must always be burned for each ERC721 to unwrap.
Examples:
1) Wrapped ERC721 Bored Ape id 1122 (unreserved)
Bored Ape Deck Items
totalSupply
0.9e18A holder of the token's Deck Item can unwrap the Bored Ape (id 1122) by burning at least 0.51e18 of the Deck Item.
2)
Wrapped ERC721 Bored Ape id1122, Bored Ape id 2233 (unreserved)
Bored Ape Deck Items
totalSupply
0.6e18A holder of the token's Deck Item can unwrap one of the two Bored Apes by burning at least 0.51e18 of the Deck Item.
If the total supply of a Deck Item ranges from 0 to 0.51, no one can unwrap the ERC721, because the Deck Item's totalSupply
is <0.51.
Wrap
When you're going to wrap an ERC721 as a Deck Item and the Deck Item totalSupply is <1, 1e18-Deck Item total supply
is obtained, and that amount must be passed in the amounts parameter of the mintItems
/safeTransferFrom
function when the ERC721 is wrapped again.
Examples:
1)
Bored Ape Deck Items
totalSupply
0.3e18When you wrap your Bored Ape, you obtain 0.7e18 of a Bored Ape Deck Item, and must pass 0.7e18 as amounts parameter of
mintItems
/safeTransferFrom
.2)
Bored Ape Deck Items
totalSupply
0.1e18When you wrap your Bored Ape, you obtain 0.9e18 of a Bored Ape Deck Item, and must pass 0.9e18 as amounts parameter of
mintItems
/safeTransferFrom
.
Why Could a Deck Item's Total Supply Be <=1?
There are two main reasons.
An address is either the first to wrap or the last to unwrap an ERC721 as a Deck Item, and as a result the Deck Item's
totalSupply
is equal to 1e18.Holders of a Deck Item burned some of them using the
burn
function of the Interoperable Item Interface (ERC20 face of the Item). Recall that an Item has two faces, allowing it to work simultaneously as an ERC1155 (using its Main Interface) and as an ERC20 (using its Interoperable Interface).
Last updated