# Carbon Auction and Marketplace This document outlines a design specification for a double-sided auction for a specified, whitelisted family of FA2 tokens. In our case this is for carbon tokens. [This contract is implemented here](https://github.com/differentialderek/cce-token-contract/blob/main/c4x.mligo) as part of the repo for the carbon project, found here: [https://github.com/differentialderek/cce-token-contract](https://github.com/differentialderek/cce-token-contract). ## Main Functionality This contract has four entrypoints: 1. `ForSale` 2. `Auction` 3. `Offer` 4. `WhitelistTokens` The last entrypoint is just for permissions and is updated by the `carbon` contract (the controller contract for this project). The first three entrypoints are all the ways in which buyers and sellers can interact with each other. The essential structure is: 1. Token owners can **post their tokens for sale** using the `ForSale` entrypoint, which itself has three components: `PostForSale`, `UnpostForSale`, and `BuyForSale` 2. Token owners can **initiate an auction** for tokens they hold, with a reserve price and a pre-specified deadline, using the `Auction` entrypoint. This has three components, which are: `InitiateAuction`, `BidOnAuction`, and `FinishAuction`. 3. Prospective buyers can **make an offer** to prospective sellers, by specifying a specific carbon token, quantity, and proposed price. They can do so by calling the `Offer` entrypoint, which itself has three components, which are: `MakeOffer`, `RetractOffer`, and `AcceptOffer`. ## Post, Unpost, and Buy Tokens For Sale The `ForSale` entrypoint has three components: `PostForSale`, `UnpostForSale`, and `BuyForSale`. To post a token for sale, a token holder calls `PostForSale` and specifies: * the token address * the token ID * quantity for sale * quantity of XTZ asked for in return * a batch number (for internal calculations to prevent collisions) When she calls `PostForSale` she transfers her tokens to the marketplace. She can take her tokens off the market by calling a corresponding `UnpostForSale` function and specifying the token address, token ID, quantity for sale, and batch number. This returns her tokens to her. A buyer can purchase tokens for sale by calling `BuyForSale`, including the XTZ asked for in the transaction, and specifying: * the token address * the token ID * quantity for sale * the batch number ## Initiate, Bid On, and Complete Auctions The `Auction` entrypoint has three components: `InitiateAuction`, `BidOnAuction`, and `FinishAuction`. To start an auction the user transfers his tokens to the marketplace, calling `InitiateAuction`, and specifying: * the token address * the token ID * quantity for sale * quantity of XTZ asked for in return * a batch number for internal calculations to prevent collisions * deadline (date/time of the end of the auction) * a reserve (minimum) price If no one bids, the token owner can redeem his tokens. While the auction is ongoing, it allows users to bid by calling `BidOnAuction`. To submit a bid, you must send your bid in; if someone outbids you, your XTZ gets returned. After the auction deadline has passed, either the auction winner or the token owner can call `FinishAuction`, which transfers the amount of the highest bid to the token owner and transfers the tokens to the winner of the auction. ## Make, Retract, and Accept Offers The `Offer` entrypoint has three components: `MakeOffer`, `RetractOffer`, and `AcceptOffer`. <!--Users can use the `Offer` entrypoint to make an offer to a token holder on tokens they hold. It also allows offer recipients to accept an offer, and for offering parties to rescind any offers they've made. For a specific token, quantity of tokens, and counterparty, an offering party can only make one offer (if they try to make a second offer the transaction fails). If they'd like to update their offer they have --> To make an offer, a user calls `MakeOffer`, and specifies the token data (token address/ID), the quantity desired, the offer of XTZ in exchange, and the party to whom they are making the offer (the counterparty). When they make an offer, they transfer their offer to the marketplace. The offering party can rescind the offer by calling `RetractOffer`, which transfers the XTZ offered back to them. To accept the offer, the counterparty calls `AcceptOffer`. In doing so they transfer their tokens to the offering party and the amount offered gets disbursed to the accepting party. ## Permissions (Whitelist) We want this auction to be specific to the carbon tokens and, least for now restricting which tokens can be bought and sold on this marketplace. To manage this, every time a project is created (through the carbon contract), it will automatically update the whitelist of the double-sided auction contract. Only tokens that are whitelisted can be posted for sale, posted for auction, or have offers made for them.