This is a brief overview of Duin.fun

Duin.fun is an anonymous NFT marketplace that allows you to own NFTs without revealing your identity or current bids on your NFT.
It does not create or manage any wallet, private data or secrets for you.

1. Each NFT is represented by a commitment.

keccak256(ownerAddress || ownerSecret) = ownershipSecret
keccak256(ownershipSecret || tokenId) = commitment₁
hash(commitment₁, commitment₂, ..., commitmentₙ) = merkleRoot

All the commitments together form the leaves of a Merkle tree

  • - Using only a valid commitment + path to the root, you can prove ownership of an NFT
  • - Revealing ownershipSecret can prove knowledge of an NFT owner but does not prove ownership
  • - Hence it is safe to share ownershipSecret anonymously, your address is not revealed

2. In order to buy an NFT, you need to place a bid by depositing ETH.

keccak256(bidderAddress || bidderSecret) = bidSecret
keccak256(bidSecret || commitment) = bidNullifier
(bidNullifier, amount, addressSent) = bid

Bids are stored on chain but the NFT for which the bid was placed is not revealed.

  • - If Bid txn is made from a different address, the original bidderAddress is not revealed to anyone
  • - A bid can made for any commitment, and can be withdrawn at any time by the sender
  • - One address is only allowed to have one active bid at a time
  • - If a bid is made on a commitment that has already been transferred, it cannot be accepted.

In order for the owner to accept your bid, you need to share the bidSecret with them.

  • - Bid secret does not reveal your address, but reveals the amount bid on the NFT
  • - Use a secure and anonymous channel to share the bid secret
  • - Sharing bid secret offline is the best option, but you can also use our discord server.

3. NFT transfers are done by an Admin account running inside a TEE.

If a bid is made on your NFT, you can transfer the NFT to the bidder and the bid amount to any address of your choice.

Private Inputs: ownerAddress, ownerSecret, tokenId, bidSecret, receiverAddress
Public Outputs: bidNullifier, bidSecret, tokenNullifier
The admin will check the following:
1. keccak256(ownerAddress || ownerSecret) = ownershipSecret
2. keccak256(ownerSecret || tokenId) = commitment
3. commitment belongs to the merkle tree
4. keccak256(bidSecret || commitment) = bidNullifier
5. keccak256(ownerAddress || ownerSecret || commitment) = tokenNullifier

If tokenNullifier is not used before in a past transaction
and If bidNullifier has not been withdrawn or used before

A new commitment is minted to the bidder's address, and bid amount is transferred to the receiver address.

The Admin runs inside a TEE and its integrity can be verified.

  • - If an Admin shuts down, or restarts. It can be replaced by another machine running the same code. Admin does not need to preserve its state.
  • - Admin cannot reveal the address of the new owner even if compromised.
  • - Admin makes two different transactions so the bid amount is not linked with the new commitment.
  • - Roadmap: Allow multiple admins, check admins' attestation on chain and replace admin with zero-knowledge proofs.

In order for the owner to accept your bid, you need to share the bidSecret with them.

  • - Bid secret does not reveal your address, but reveals the amount bid on the NFT
  • - Use a secure and anonymous channel to share the bid secret
  • - Sharing bid secret offline is the best option, but you can also use our discord server.

4. A few things to keep in mind.

Losing access to your secret means losing access to your NFT as well as potentially any bids you might have placed.

  • - We use a global secret for all your transactions, so keep changing it between trades.
  • - If you share your ownershipSecret, the price of an NFT can be leaked.
  • - However if you do not share your ownershipSecret, your bid will never be accepted.

Roadmap:

  • - Allow multiple admins to be used for transfers by checking admins' attestation on chain.
  • - Use indexer for tracking events so that admins do not run out of memory.
  • - Replace Admin with zero-knowledge proofs.