Skip to content

hcheng826/anon-exchange-v2

Repository files navigation

Anon Exchange v2

An extension of the previous version of Anonymous NFT Exchange. Added functionalities to allow listing of ERC20 tokens.

Notes for ETH online

Mantle

Deployed contract: https://explorer.testnet.mantle.xyz/address/0xDD98f5E7269f8eCfb62b77CC8bCbf791BEFF8cC2 Tweet: https://x.com/lilioo826/status/1716009796862930957?s=20

Polygon

Had some issue deploying to zkEVM testnet, getting error not enough step counters to continue the execution. Instructed by polygon teammember to deploy to Mumbai instead: https://discord.com/channels/554623348622098432/819516356616781834/1165545531871870996

Scroll

The deployment of the contract got stuck: https://sepolia.scrollscan.dev/tx/0x940d964729e7af1c350fea0ea927cf4122a5fd5844db97470eb7101696964095. Tested on fork mode locally is it's working ok.

Simplicity Assumption

For the simplicity of the initial system, we make the assets all traded at 0.01 ETH. It is possible to extend to other price tiers in the future.

System Components

User: Asset Seller

Seller can perform following 2 operations

  • List on the smart contract and get Semaphore id
  • Claim ETH using the Semaphore id after the asset is sold. A new address should be provided to receive the ETH

User: Asset Buyer

Buyer can perform following 2 operations

  • Deposit ETH to the smart contract and get Semaphore id. With the id buyer is eligible to buy the listed assets
  • Buy the asset with the proof generated by Semaphore id. A new address should be provided to receive the asset

System: Semaphore Groups

Smart Contract

There are 2 Semaphore groups to achieve the anonymous of seller and buyer.

  1. ASSET_SOLD_SELLER_GROUP_ID: Sellers whose asset got sold
  2. ETH_DEPOSITED_BUYER_GROUP_ID: Buyers who have deposited the ETH

There are mainly 6 functions

  1. list(): called by seller
  2. deposit(): called by buyer
  3. buyAndClaim(): can be called by anyone, triggered by buyer
  4. claimETH(): can be called by anyone, triggered by seller
  5. withdrawETH(): called by buyer to withdraw unspent ETH
  6. delist(): called by seller to delist unsold asset

Transaction flow

Sellers Lists Asset

When seller lists the asset on the exchange, a Semaphore identity is generated. Seller needs to note down the private Semaphore id (trapdoor and nullifier). The smart contract will record the asset with the corresponding public Semaphore id. AnonEx-list asset

Buyers Deposits ETH

Buyer needs to deposit ETH before it can buy asset. When buyer deposits, a Semaphore id is generated. Buyer needs to note down the private id (trapdoor and nullifier). The smart contract will add the public id into ETH_DEPOSITED_BUYER_GROUP_ID. AnonEx-deposit-eth

Buyer Purchases Asset

Buyer submits the Semaphore proof that anonymously prove its membership of ETH_DEPOSITED_BUYER_GROUP_ID. Smart contract will verify the proof and signal the operation to prevent double spending. Buyer will provide a fresh address to receive the asset. Additionally, the Semaphore id of seller associated with the sold asset is added to ASSET_SOLD_SELLER_GROUP_ID. AnonEx-claim-eth

Seller Claims ETH for Asset Sold

Seller who wants to claim the ETH will submit the proof generated by its private Semaphore id, anonymously proving that it's a member of NFT_SOLD_SELLER_GROUP_ID and eligible to claim ETH. Smart contract will verify the proof, and signal the operation so it cannot be double claimed. Seller will also provide a fresh address to receive the ETH. AnonEx-buy-asset

Anonymity

Note that transaction for buying asset and claiming ETH can be sent from any address as long as the proof is valid. To remain anonymous the approach of this project is to maintain a relayer. The relayer will just submit the transaction for the user. From public people can only know Buy or Seller is one in the group but wouldn't be able connect the NFT purchase to the original payer.

Development 🛠️

Populate the environment variables in .env according to .env.example

Smart Contracts

Go to contracts/

  1. Install dependencies
    yarn
  2. Set up snark files
    yarn download:snark-artifacts
  • Run test

    yarn test
  • Coverage

    yarn coverage
  • Local network deployment for developemnt

    npx hardhat node
    
    # in another terminal
    yarn deploy:local

Frontend

The project uses Next.js framework and Vercel for deployment

To config the contract addresses

  1. Fill in the addresses in wagmi.config.ts
  2. Run yarn wagmi to genereate the file abis.ts
  • Start Local

    yarn start
  • Local watch mode

    yarn dev
  • Build

    yarn build