Multidimensional Clones
Ditto Protocol creates a queue of clones. Each clone in that queue represents an eventual claim on some unique NFT. The clone at the front of the queue has the immediate claim on the underlying NFT when sold through the protocol.
As soon as this trade happens, the NFT is transferred to that clone owner, and the clone is burned.
Here's a more technical description for accuracy -
A queue Q
is identified by a parameter protoId
which is a hash of
- the underlying
ERC721
/ERC1155
contract address, sayA
, tokenId
ofA
, sayid
,- the
ERC20
contract, sayB
, - and a boolean
floor
.
All together, this means that the clones part of this queue want a claim on the NFT represented by address A
with tokenId id
, and they are bidding using ERC20 token B
. If floor
is true
, the clones are not bidding for any specific token in the NFT collection. In this case, id
must have a constant value - FLOOR_ID
.
A (protoId, index)
tuple uniquely identifies a clone, where index
refers to the 0
-indexed position in the queue. In fact, cloneId
is defined as the hash of protoId
and index
.
A bidder is allowed to bid on an existing clone, or a new clone which is pushed at the end of the queue. If no clone is dissolved, the index of the clones in the queue will be 0,1,2,...
and so on. But since, a clone can be dissolved, at any moment the queue will be missing the indexes corresponding to the dissolved clones.
Next, we go into detail on the actions you can take through Ditto protocol:
Duplicate
Open or buy out a future on a particular NFT or floor Future of an ERC721 or ERC1155 collection. The ownership of this Future is represented via an ERC1155 token called a clone
. The caller specifies:
_ERC721Contract
: NFT contract, also referred to as the "Underlying NFT"._tokenId
: the specific token ID of the NFT contract. For floors,_tokenId
has to beFLOOR_ID
._ERC20Contract
: ERC20 token which is used to buy the clone,_amount
: amount of ERC20 token to buy the clone. Has to be at least the amount returned bygetMinAmountForCloneTransfer(cloneId)
,floor
: a boolean value determining if the purchase if for a floor Future.index
: position in the queue of the claim on the underlying NFT.
If the bid is successful, this call returns two parameters:
cloneId
: an ERC1155 token ID owned by the buyer.protoId
: identifier of the queue in which the clone was minted.
function duplicate(
address _ERC721Contract,
uint _tokenId,
address _ERC20Contract,
uint128 _amount,
bool floor,
uint index
) external returns (uint cloneId, uint protoId);
Dissolve
A clone owner can choose to burn the clone, which in effect, removes their claim on the underlying NFT.
- Their bid is returned after subtracting the subsidy and fee.
- The subsidy is passed to the clone next in the queue.
- The corresponding index is removed from the queue.
function dissolve(uint protoId, uint cloneId);
Underlying NFT Trade
If an underlying NFT owner decides to sell the NFT via Ditto, they just have to transfer it DittoMachine
contract. This triggers a trade where the NFT to the clone owner at the front of the queue, and the subsidy amount plus clone's worth is transferred to the seller. It also burns the clone and moves the head of the queue to the next clone.