================================================================================ CARBONCORE DEVELOPER GUIDE #06 OTC MARKETPLACE SYSTEM ================================================================================ PRINCIPLE: Decentralized peer-to-peer carbon credit trading platform ================================================================================ MARKETPLACE ARCHITECTURE ================================================================================ Smart Contracts: OTCMarketInterface: 0xDAde447FCC8B2480c76cc8E0be23eb5772966C21 - Semantic layer over RequestManager - Order creation and management - Instant Buy functionality OTCMarketIndex: 0xd154C16A5d1fB9CE16B88F0c76593D1C28Bd046e - Order indexing and search - Filtering and sorting - RFQ to response linking Frontend Components: deals.html - Main marketplace interface deals-manager.js - State management and UI deals-contract-service.js - Contract interaction Service Dependencies: UnifiedTokenManager - Token operations MetadataService - Deal metadata TerritoryDetailsService - Territory information ================================================================================ DEAL TYPES ================================================================================ Type 1: Request for Quote (RFQ) - Buy Request Creator: Buyer Direction: Buyer seeks carbon credits Requirements: Specified territory/vintage criteria Process: Open request → Seller responses → Buyer selection Type 2: Direct Offer - Response to RFQ Creator: Seller Direction: Response to specific RFQ Requirements: Tokens deposited in escrow Process: Seller deposits → Buyer accepts → Instant exchange Type 3: Market Offer - Open Sell Order Creator: Seller Direction: Open to any buyer Variants: Standard, Instant Buy, KYC Required Process: List tokens → Buyer purchases → Exchange Type 4: Instant Buy - Pre-funded Offer Creator: Seller Direction: Immediate purchase available Requirements: Tokens in escrow, fixed price Process: Tokens locked → Buyer pays → Instant transfer ================================================================================ RFQ CREATION WORKFLOW ================================================================================ Step 1: Authentication Check Requirement: BUYER_ROLE Check: roleManager.hasRole(userTokenId, BUYER_ROLE) Step 2: Form Data Collection Fields: - carbonAmount (number of credits needed) - maxBudget (maximum willing to pay) - paymentToken (USDT/USDC/Mock USD) - territoryTypes[] (Forest, Wetland, etc.) - minVintage, maxVintage (year range) - countries[] (geographic preference) - minCO2Absorption (minimum threshold) - requiresKYC (boolean) - additionalTerms (text) Step 3: Metadata Structure { "metadataType": "RFQ", "version": "1.0", "requirements": { "territoryTypes": ["Forest", "Wetland"], "minVintage": 2020, "maxVintage": 2025, "countries": ["USA", "Canada"], "minCO2Absorption": 50000, "requiresKYC": true, "additionalTerms": "Gold Standard certification required" }, "contactPreferences": { "preferredCommunication": "in-platform", "timezone": "UTC-5", "responseTime": "24h" } } Step 4: Token Amount Parsing const carbonAmountWei = await tokenManager.parseAmount( carbonAmount, ethers.constants.AddressZero // Generic carbon token ); const maxPaymentWei = await tokenManager.parseAmount( maxBudget, paymentTokenAddress ); Step 5: Contract Call const tx = await otcMarketInterface.createBuyOrder( carbonAmountWei, maxPaymentWei, paymentTokenAddress, JSON.stringify(metadata) ); const receipt = await tx.wait(); Step 6: Extract Order ID const event = receipt.events.find(e => e.event === 'BuyOrderCreated'); const orderId = event.args.orderId.toString(); const discussionId = event.args.discussionId.toString(); ================================================================================ INSTANT OFFER CREATION WORKFLOW ================================================================================ Step 1: Token Selection Source: Token management module Data: tokenAddress, territoryId, balance Step 2: Balance Check const balanceCheck = await tokenManager.checkSufficientBalance( tokenAddress, offerAmount, userWallet ); if (!balanceCheck.sufficient) { throw new Error(`Insufficient balance: need ${balanceCheck.deficit}`); } Step 3: Token Approval const spender = window.appConfig.contractAddresses.otcMarketInterface; await tokenManager.approve( tokenAddress, spender, offerAmount ); Step 4: Metadata Creation { "metadataType": "Offer", "version": "1.0", "offerType": "instant_buy", "tokenDetails": { "territoryId": "24", "territoryName": "Amazon Conservation Alpha", "territoryType": "Forest", "location": { "country": "Brazil", "region": "Amazonas" }, "vintage": 2024, "tokenSymbol": "CCT24-2025" }, "pricingDetails": { "pricePerToken": 9.5, "instantBuy": true, "minimumPurchase": 1, "maximumPurchase": 1000 } } Step 5: Create Offer with Deposit const amountWei = await tokenManager.parseAmount(amount, tokenAddress); const priceWei = await tokenManager.parseAmount(totalPrice, paymentToken); const tx = await otcMarketInterface.createSellOrderWithDeposit( tokenAddress, amountWei, priceWei, paymentToken, JSON.stringify(metadata) ); Step 6: Confirmation Result: Order created, tokens in escrow, instant buy enabled ================================================================================ INSTANT BUY EXECUTION ================================================================================ Step 1: Verify Instant Buy Status const offer = await otcAPI.getOrder(offerId); if (!offer.carbonTokensInEscrow) { throw new Error('Tokens not in escrow - instant buy unavailable'); } Step 2: Calculate Payment const carbonAmount = ethers.utils.formatEther(offer.carbonAmount); const paymentAmount = ethers.utils.formatUnits( offer.paymentAmount, await tokenManager.getTokenInfo(offer.paymentToken).decimals ); Step 3: Check Payment Balance const balanceCheck = await tokenManager.checkSufficientBalance( offer.paymentToken, paymentAmount, buyerWallet ); Step 4: Approve Payment Token await tokenManager.approve( offer.paymentToken, otcMarketInterface, paymentAmount ); Step 5: Execute Purchase const tx = await otcMarketInterface.executeInstantBuy(offerId); const receipt = await tx.wait(); Step 6: Automatic Exchange Blockchain executes: 1. Transfer payment from buyer to seller 2. Transfer tokens from escrow to buyer 3. Update order status to COMPLETED 4. Emit InstantBuyExecuted event ================================================================================ DEAL DISCOVERY & FILTERING ================================================================================ Function: loadMarketData() Process: 1. Find maximum order ID (binary search) 2. Load orders in batches (20 per batch) 3. Filter by type (RFQ, Offer, Response) 4. Load metadata for each order 5. Enrich with territory data Filters Available: - Deal Type: RFQ, Direct Offer, Market Offer - Territory Type: Forest, Wetland, Agricultural, etc. - Vintage Year: 2020-2025 - Price Range: Min-Max per token - Geography: Countries/Regions - Payment Currency: USDT, USDC, Mock USD - Status: Active, Pending, Completed Sorting Options: - By Creation Date (Newest/Oldest) - By Price (Low to High / High to Low) - By Amount (Small to Large / Large to Small) - By Vintage Year (Recent to Old / Old to Recent) Implementation: const filtered = allOrders.filter(order => { if (filters.dealType && order.orderType !== filters.dealType) return false; if (filters.territoryType && !matchesTerritoryType(order, filters.territoryType)) return false; if (filters.minPrice && order.pricePerToken < filters.minPrice) return false; // ... additional filters return true; }); const sorted = filtered.sort((a, b) => { if (sortBy === 'price-asc') return a.pricePerToken - b.pricePerToken; if (sortBy === 'price-desc') return b.pricePerToken - a.pricePerToken; // ... additional sort options }); ================================================================================ METADATA MANAGEMENT ================================================================================ Service: MetadataService Purpose: Store and retrieve deal metadata Storage: CommentManager contract + Direct contract calls Save Metadata: await commentManager.addComment( discussionId, 0, // parentId (root comment) JSON.stringify(metadata) ); Retrieve Metadata: // Primary method: Direct contract call const metadata = await otcMarketInterface.getOrderMetadata(orderId); // Fallback: Through CommentManager const comments = await commentManager.getDiscussionComments(discussionId); const metadataComment = comments.find(c => isValidJSON(c.content)); const metadata = JSON.parse(metadataComment.content); Validation: function validateMetadata(metadata) { // Required fields if (!metadata.metadataType) return false; if (!metadata.version) return false; // Type-specific validation if (metadata.metadataType === 'RFQ') { if (!metadata.requirements) return false; } else if (metadata.metadataType === 'Offer') { if (!metadata.tokenDetails) return false; if (!metadata.pricingDetails) return false; } // Size limit (8KB) const size = new Blob([JSON.stringify(metadata)]).size; if (size > 8192) return false; return true; } ================================================================================ UI COMPONENTS ================================================================================ RFQ Card Display:
Buy Request 7 days left
1,000 Credits Needed
Budget: $10,000
Payment: Mock USD
🌍 Forest, Wetland 📅 Vintage: 2023-2025 📍 USA, Canada ✓ KYC Required
Instant Offer Card Display:
Sell Offer Forest ⚡ Instant Buy
CCT24-2025
Amazon Conservation Alpha
📍 Brazil
Vintage 2024
Amount: 1,000 credits
Price: $9.50/token
Total: $9,500 Mock USD
Tokens secured in escrow 💫 Immediate exchange!
================================================================================ DEAL LIFECYCLE STATES ================================================================================ Order Statuses (from RequestManager): 0 - PENDING: New order, awaiting actions 1 - APPROVED: Approved, ready for execution 2 - REJECTED: Rejected by counterparty 3 - REVISION: Under revision/negotiation 4 - COMPLETED: Successfully executed 5 - ARCHIVED: Closed/expired Additional Flags: carbonTokensInEscrow: boolean paymentInEscrow: boolean requiresKYC: boolean instantBuyAvailable: boolean State Transitions: RFQ Created → PENDING Seller Responds → PENDING (with escrow) Buyer Accepts → APPROVED Exchange Completes → COMPLETED Instant Offer Created → PENDING (with escrow) Buyer Purchases → COMPLETED (single transaction) ================================================================================ SECURITY & VALIDATION ================================================================================ Contract-Level Checks: - BUYER_ROLE required for RFQ creation - Balance verification before offer creation - Escrow mechanism for fund security - ReentrancyGuard for attack protection - Pausable for emergency stop UI-Level Validation: - Form input sanitization - Amount range validation - Token address verification - Balance sufficiency check - Gas fee estimation - Confirmation dialogs for critical operations Error Handling: TRY { // Operation } CATCH (error) { if (error.code === 4001) { // User rejected transaction } else if (error.message.includes('insufficient funds')) { // Insufficient balance } else if (error.message.includes('Only territory owner')) { // Permission denied } else { // Generic error } } ================================================================================ PERFORMANCE OPTIMIZATION ================================================================================ Binary Search for Max Order ID: - Exponential growth to find upper bound - Binary search for exact maximum - Cache result for 5 minutes - Adaptive search range Batch Loading: - Load 20 orders per batch - Max 3 concurrent batches - Adaptive delays (100-200ms) - Early termination on errors Caching Strategy: - Metadata: 5 minutes - Token info: 1 hour - Territory data: In global state - Order list: 2 minutes Pagination: - Client-side for < 100 orders - Server-side for > 100 orders - Lazy loading on scroll - Virtual scrolling for large lists ================================================================================ INTEGRATION WITH OTHER MODULES ================================================================================ Token Management: Event: "List for Sale" button Action: Navigate to deals.html with pre-filled form Data: tokenAddress, amount, territory info Territory Details: Tab: "Deals" in details modal Display: Active offers for territory tokens Actions: Create offer, view deal history Dashboard: Widget: Active deals summary Metrics: RFQs, offers, pending actions Quick Actions: View marketplace, respond to RFQ Profile: Section: My deals history Stats: Total traded, average price Link: Full marketplace access ================================================================================