Dexhune-P is an Automated Market Maker (AMM) x Orderbook Hybrid, the system allows a scaled down order matching system where instead of directly matching orders, order balances are used for settlement, respecting max/min order price bounds but enforcing impactPrice. Price is derived from the cumulative balances of buy and sell orders, therefore each order has the potential to move the market. impactPrice is an AMM concept which estimates the price change an order may have after it is settled, this is important for preventing liquidity draining, where a user buys and immediately sells with profit. With impactPrice a user either makes no profit or loses if no one else buys.
OMF "Marker Foundry : Oracle Type" is a variant of MFP (Marker Foundry : Pairing Type), OMF derives a fixed price from an oracle address, calculating a price conversion to XAU (the base asset). The OMF system aims to reduce liquidity fragmentation as seen with existing price pegged assets (stablecoins, RWAs) and extreme price fluctuations, by merging the issuance/redemption mechanism with the market.
The name Marker Foundry is derived from the fictional setting of Dead Space™ where "Markers" are sources of unlimited energy but at a dark cost. In the far flung future, mankind, in desperation, replicates these markers, fulfilling a cosmic evolutionary cycle.
Dexhune-P operates via MFPAgent or OMFAgent to deploy MFPListingTemplate or OMFListingTemplate and CCLiquidityTemplate contracts for unique token pairs. MFPListingTemplate or OMFListingTemplate serve as the order book, enabling order creation, cancellation, and settlement via CCOrderRouter, MFPSettlementRouter, and MFPLiquidRouter. It uses the relative presence of TokenB / TokenA for pricing (inverted calculation on OMF based on oracle prices), enables partial fills, tracking historical data and balances. CCLiquidityTemplate enables deposits, withdrawals, fee claims, and payouts, storing liquidity details and slot data. CCLiquidityRouter handles deposits, partial withdrawals with compensation, and fee calculations, while MFPLiquidRouter settles orders using liquidity balances, charging between 0.05% and 50% in fees (regular settlement has zero fees). CCGlobalizer and TokenRegistry ensure cross-contract order and balance consistency. Pagination (maxIterations, step) optimizes queries, and relisting supports system upgrades.
The MFPAgent contract (Solidity ^0.8.2) manages deployment and initialization of token pair listings and liquidity contracts, serving as a central hub for tracking listings.
- Listing Management: Deploys
MFPListingTemplateandCCLiquidityTemplateviaMFPListingLogicandCCLiquidityLogicusing_deployPair. Supports token-token (listToken) and token-native (listNative) pairs, with relisting (relistToken,relistNative) restricted to original listers. - State Tracking: Uses
getListing,getLister,listingsByLister,allListings,allListedTokensmapped to TokenA / TokenB token pairs and lister details. - Initialization: Configures contracts with routers, tokens via
_initializeListing,_initializeLiquidity. - Lister Management: Supports
transferListerand paginated queries (getListingsByLister,queryByAddressView) withmaxIterations. - Validation: Ensures non-zero addresses, unique token pairs, emits
ListingCreated,ListingRelisted,ListerTransferred.
- MFPListingLogic: Deploys listing contracts via
deploywith CREATE2, ensuring deterministic addresses. Can be updated by owner. - CCLiquidityLogic: Deploys liquidity contracts similarly, linked to listings via
liquidityAddressView. Can be updated by owner.
- CCGlobalizer: Optionally set via
setGlobalizerAddress, enabling order and liquidity globalization. Listings callsetGlobalizerAddressif configured, allowing cross-contract order tracking. Owner sets or resets this address.
- TokenRegistry: Tracks token balances for users, integrated via
registryAddress. Used by listings for balance queries, ensuring consistent token data across the system. Owner sets or resets this address.
- Restricts critical functions to owner.
- Uses try-catch for external calls, ensuring graceful degradation.
- Validates inputs (e.g., non-zero addresses, token pair uniqueness) to prevent errors.
- Opt-in updates via relisting or router-resets ensure that the system is upgradable and secure. If routers are updated the new addresses can be pushed via
resetRouterson theMFPListingTemplateandCCLiquidityTemplate, restricted to the original lister. Globalizer and Token Registry cannot be changed on the listing template without relisting. Liquidity template fetches latest Globalizer and Token Registry from Agent. Templates can only be updated by relisting. Agent retains old pairs after relisting and continues to validate them, butgetListingand other queries return only the latest listing.
- Supports pagination (
maxIterations,step) for efficient queries.
The OMFAgent contract (Solidity ^0.8.2) based on MFPAgent, manages listings with a fixed baseToken (tokenB) and oracle parameters for pricing.
- Listing Management: Same as MFP but does not support Native listing/relisting, restricts tokenB to
baseToken. - State Tracking: Only maps tokenA to a listing, all TokenB's are
baseToken, this affectsgetListinggetLister,listingsByLister,allListings,allListedTokens. - Initialization: Configures listings with oracle parameters (
oracleAddress,oracleFunction,oracleBitSize,oracleIsSigned,oracleDecimals) andbaseTokenvia_initializeListing. - Oracle Integration: Sets
baseOracleParamsfor base token pricing (e.g.,tokenAUSDPrice / baseTokenUSDPrice). - Lister Management: Same as MFP.
Same as MFP.
- Same as MFP.
The MFPListingTemplate contract (Solidity ^0.8.2) serves as the central order book. The contract ensures secure, normalized (1e18 decimals) handling of token pairs (tokenA, tokenB), with price calculations derived from own balances. Router-only access for write functions.
-
CCOrderRouter: Creates/cancels orders via
ccUpdate. -
MFPSettlementRouter: Settles orders using listing template balances, respects order max/min price bounds with partial fills, accounts for slippage. Fetches pending orders using; (
pendingBuyOrdersView,pendingSellOrdersView) and updates order states viaccUpdate. -
MFPLiquidRouter: Settles only the caller's buy/sell orders using liquidity balances (charges a fee between 0.05% and 50% depending on liquidity usage), transfers principal to liquidity template and updates liquid balances (
xLiquid,yLiquid). Only uses listing template for fetching liquidity address via orders vialiquidityAddressView, fetches orders usingmakerPendingOrdersViewand updates order states viaccUpdateand transfers principal viatransactTokenortransactNative. -
CCLiquidityRouter: Manages deposits - withdrawals - fee claims - and depositor changes on liquidity contract, only uses
liquidityAddressViewon listing template. -
Double Impact: When an order is created it pushes the price upwards or downwards because it adds more of a given token. This is illustrated as follows;
Price = TokenB Balance / TokenA BalanceExample;200 / 100 = 2Buy orders use TokenB to acquire TokenA, therefore if a buy order is created with 5 TokenB, this increases the contract's TokenB balance;205 / 100 = 2.05When the buy order is settled this moves an equivalent amount at impact price, the impact is calculated as a simulation of post-settlement balances, in this case2.439024390243902would be moved if settled at current price, this would push the price to;205÷97.56097560975609 = 2.10125Which is theimpactPrice, the order is then settled at the impact price rather than current price. This means for their 5 TokenB, they would be settled for2.379535990481856TokenB not2.439024390243902and definitely not2.5(at the original nominal price before they created the order).
- Order Management: Tracks buy/sell orders using
makerPendingOrders,pendingBuyOrdersView, andpendingSellOrdersView. Stores order details inBuyOrderCore,BuyOrderPricing,BuyOrderAmounts,SellOrderCore,SellOrderPricing, andSellOrderAmounts. Updates are processed viaccUpdatewithBuyOrderUpdateorSellOrderUpdatestructs, ensuring status (cancelled, pending, partially filled, filled) and amount consistency. - Price Calculation: Computes real-time prices via
prices(0), using own balances (IERC20.balanceOf) normalized to 1e18. Handles edge cases (e.g., zero balances) by returning minimal price (1).
Price effectively tracks TokenA -> TokenB. Example; LINK/USDT with a price of 35 indicates that LINK is worth 35 USDT. A buy order would require; 35 USDT / 35 = 1, and sell; 1 LINK * 35 = 35.
- Balance Tracking: Monitors token balances (
volumeBalances) for tokenA and tokenB, normalized for consistency, supporting real-time queries for routers. - Liquidity Integration: Interfaces with
ICCLiquidityTemplatevialiquidityAddressViewto fetchxLiquid,yLiquid,xFees, andyFees, enabling additional data queries viaCCDexlytan. - Historical Data: Maintains
HistoricalDataarray and_dayStartIndicesfor tracking price, balances, and volumes at midnight timestamps, created viaccUpdatewithHistoricalUpdatestruct. Historical volumes are updated withinBuyOrderUpdateorSellOrderUpdateusingpendingandamountSentchanges. - Security: Restricts updates to validated routers (
routersmapping,routerAddressesView) viaICCAgent.getRouters. Uses try-catch for external calls, emitting events (OrderUpdated,BalancesUpdated,UpdateFailed) for graceful degradation. - Token Registry and Globalizer: Supports
TokenRegistryfor global balance storage andGlobalizerfor order globalization, ensuring cross-contract consistency.
The OMFListingTemplate contract (Solidity ^0.8.2) based on MFPListingTemplate manages order book with oracle-based pricing functionality, handling token pairs (tokenA, baseToken), deriving price from a set oracle address and parameters.
Same as MFPListingTemplate with a key nuance. Because MFPSettlementRouter and MFPLiquidRouter calculate impact price by calculating an order's impact on liquidity balance and projecting that onto the listing price; they create a unique restriction where even though orders do not move the price of an OMF Listing, they still have to be within certain limits to prevent overuse of opposite listing balances or liquidity balances as a whole. (Also, I didn't want to create OMF variants of the routers without impact price because that's unnecessary work).
- Price Calculation: Differs primarily from
MFPListingTemplatein how it determines price. It uses TokenA oracle (oracleAddress,oracleFunction) and base token oracle forprices(0)(tokenAUSDPrice / baseTokenUSDPrice), normalized to 1e18. It takes priceA and priceB to calculate a final priceC. This is because Chainlink Data Feeds typically list assets as ASSET/USD where all tokenB's are assumed to be USD. But because our base token is now pegged to XAU/USD, it is not possible to directly peg every asset, so this double conversion is used. Example;LINK/USD -> XAU/USD35 / 3500 = 0.01This means 1 LINK is equal to 0.01 XAU. Buy orders convert tokenB to TokenA as;Order Amount / priceExample;10 XAU / 0.01 = 1000 LINKWhereas sells convert TokenA to TokenB;Order Amount * priceExample;1000 LINK * 0.01 = 10 XAU.
The CCLiquidityTemplate contract (Solidity ^0.8.2) manages liquidity allocations, enabling deposits, withdrawals, fee claims, and payouts.
-
CCLiquidityRouter: Calls
ccUpdateto adjust liquid balance (xLiquid/yLiquid) and liquidity slot data during deposit.- Calls transfer functions (
transactToken/transactNative) during withdrawal, withccUpdatefor liquid balance and slot data updates. - Similar interactions for fee claims
- Similar interactions for depositor changes.
- Fetches
liquidityAddressView,liquidityDetailsView,getXSlotView,getYSlotView,userXIndexView,userYIndexView,liquidityAmounts, during various operations.
- Calls transfer functions (
-
MFPLiquidRouter: Similar interactions as
CCLiquidityRouter.
- Storage:
LiquidityDetails: StoresxLiquid,yLiquid(liquidity amounts),xFees,yFees(accumulated fees),xFeesAcc,yFeesAcc(cumulative fee snapshots).xLiquiditySlots,yLiquiditySlots: Map slot indices toSlotstructs (depositor,recipient,allocation,dFeesAcc,timestamp).activeXLiquiditySlots,activeYLiquiditySlots: Track active slot indices.userXIndex,userYIndex: Map user addresses to their slot indices.longPayout,shortPayout: Store payout details for leverage markets (makerAddress,recipientAddress,required,filled,amountSent,orderId,status).longPayoutByIndex,shortPayoutByIndex,activeLongPayouts,activeShortPayouts,userPayoutIDs,activeUserPayoutIDs: Track payout order IDs.nextPayoutId: Tracks next payout ID, incremted during payout creation.routers,routerAddresses: Track authorized routers.listingAddress,tokenA,tokenB,listingId,agent: Store contract configuration.
- Updates: Handles up to (10) update types as follows;
0: SetsxLiquid/yLiquid.1: Adds toxFees/yFees.2/3: UpdatesxSlot/ySlotdetails (allocation, increases or reducesxLiquid/yLiquid,userXIndex/userYIndex).4/5: Changes slotdepositor.6/7: Updates slotdFeesAcc(Is needed during fee claims to reset a depositor's eligible fees).8/9: Subtracts fromxFees/yFees.- Payouts are created and updated via
ssUpdate.
- Token Registry and Globalizer: Same as
MFPListingTemplate, but fetches addresses fromMFPAgent. - Security: Same as
MFPListingTemplate.
As seen in CCListingTemplate.
- Segregates ERC20 token order creation; (
createTokenBuyOrder,createTokenSellOrder,) from Native token order creation; (createNativeBuyOrder,createNativeSellOrder) - Allows singular order cancelation orders (
clearSingleOrder), distinct from bulk cancellation; (clearOrders).
- Token/ETH Transfers: Validates ERC20 transfers and ETH transfers to
CCListingTemplate, ensuring sufficient allowance and successful transfer before order execution. - Order Data: Allows order creation with max/min price bounds, uses
recipientfield for user supplied order recipient. - Validation: Uses
onlyValidListingmodifier to verify listing viaCCAgent, ensuring non-zero liquidity address and distinct token pairs. - Payout Settlement: Fetches active payout IDs from
CCLiquidityTemplateusingactiveLongPayoutsViewandactiveShortPayoutsView, settles payouts using liquidity balance viatransactTokenortransactNative, updates liquidity balances usingccUpdateatCCLiquidityTemplate. - Data Queries: Retrieves maker orders via
makerPendingOrdersView, order details viagetBuyOrderCore,getSellOrderCore,getBuyOrderAmounts,getSellOrderAmounts, and token details viatokenA,tokenB,decimalsA,decimalsBonCCListingTemplate.
- Uses
nonReentrantmodifier to prevent reentrancy. - Peng
ReentrancyGuardusesreentrancyExceptionwithaddRentererandremoveReentererrestricted to contract owner. - Emits
TransferFailedfor failed transfers with reasons. - Validates inputs (maker, recipient, amount) and token types before processing.
- Ensures normalized amounts for consistency across token decimals.
Handles order settlement for MFPListingTemplate using direct transfers.
- Order Settlement: Iterates over pending orders using
pendingBuyOrdersView/pendingSellOrdersView. Processes in batches withstepandmaxIterations(e.g., orders [2,22,23,24,30],step=1 (zero based indexing),maxIterations=3 processes 22,23,24). - Order Validation: Ensures non-zero pending amounts and status (1 or 2) in
_validateOrder. - Balance Handling: Uses
transactToken/transactNativefor transfers, checking post-transfer balances. - Update Application: Applies updates via
ccUpdatewithBuyOrderUpdate/SellOrderUpdatestructs. Updatespending,filled,amountSent, andstatus(2 for partial, 3 for filled) viaccUpdate. - Historical Data: Creates
_createHistoricalEntryfor price/volume analytics. - Security: Uses
nonReentrantand try-catch, reverting with detailed reasons. Returns "No orders settled: price out of range or transfer failure" if no orders settle, ensuring graceful degradation. - Partial Fills: If an order cannot be fully settled at the current price without violating the order's min/max price bounds, the system calculates
swapAmountto determine the max amount that can be swapped within the price bounds. IfswapAmountis zero the order is skipped. - Impact Price: This represents the post-swap balances caused by the order, is used to simulate the impact the order will have on price. All settlement operations use impact price as an additional control measure, impact price cannot be above or below max/min price bounds, otherwise the order will be settled using partial fills.
As seen in MFPListingTemplate and CCLiquidityTemplate.
-
Liquid Settlement: Uses liquidity balances to settle active or pending orders, restricts settlement using impact price (as seen in
MFPSettlementRouter) for consistency. -
Pagination: Limits processing up to
maxIterationsorders starting fromstep. E.g; if a pending orders array has (5) orders, "2,22,23,24,30", the user or frontend specifies astep"1" (zero based indexing)andmaxIterations"3" this limits processing to orders "22,23,24". -
Fee Handling: Deducts fees (between 0.05% to 50% depending on how much of the liquidity balance was used, e.g 83% usage will charge 8.3% in fees). Records fees in
CCLiquidityTemplateusingccUpdate. -
Liquidity Updates: Transfers principal to liquidity contract and adjusts
xLiquid/yLiquidusing normalized amounts (1e18 decimals) to ensure consistency. -
Historical Data: Creates
HistoricalUpdateentries before processing orders, capturing currentvolumeBalancesandprices(0)fromMFPListingTemplatefor accurate tracking. -
Security: Uses
nonReentrantmodifier to prevent reentrancy. Validates listings viaonlyValidListingmodifier. -
Full Settlement: Only Executes full settlement of pending or active orders, can settle orders that were previously partially settled but does not create partial settlement.
-
Listing Balances: The
volumeBalancesfunction inMFPListingTemplateis used to check available token balances (xBalance,yBalance) before settling orders. It ensures sufficient balances exist to process buy/sell orders without reverting due to insufficient funds. For buy orders, it verifiesyBalance(TokenB) is adequate for the principal; for sell orders, it checksxBalance(TokenA). -
Graceful Degradation: The system avoids reverts for non-critical failures. Such as;
- No Pending Orders: If
makerPendingOrdersViewreturns an empty array orstepexceeds the array length, the contract emits aNoPendingOrdersevent and returns without reverting. - Insufficient Liquidity: If
volumeBalancesindicates zeroxBalance(for sell orders) oryBalance(for buy orders), it emits anInsufficientBalanceevent and exits without processing, avoiding a revert. - Invalid Pricing: If the order's pricing (
impactPrice) is outsidemaxPrice/minPrice, it emits aPriceOutOfBoundsevent, skips the order, and continues processing others, ensuring batch operations proceed. - Zero Pending Amount: If an order's
pendingAmountis zero,_processOrderBatchskips it without reverting, continuing to the next order.
- Null Impact: Because all orders settled using
MFPLiquidRoutertransfer principal from the listing template to the liquidity template ; they have no long term impact on price. The original order creation momentarily increases/reduces the price but once settled usingx/yLiquidthe price increase/reduction is completely negated.
As seen in CCListingTemplate and CCLiquidityTemplate.
- Native Handling: The system splits Native (
depositNativeToken) and ERC20 (depositToken) deposit functions. - Partial Withdrawals: The system allows a valid depositor to withdraw a part of their allocation while retaining the rest, unclaimed fees are forfeit.
- Compensation: The system allows users to specify a
compensationAmountduring withdrawals, this is the opposite token from that which the user provided. The system validates ownership and sufficient slot allocation (primary + converted compensation). converted compensation is gotten by converting the statedcompensationAmountto a relative value in the allocation token. Using the current price fromCCListingTemplateusingprices. The system limits withdrawals to the slot allocation the user has. - Fee Calculation: Elligible fees are calculated based on liquidity and volume contribution. The contract computes
contributedFeesasx/yFeesAcc(total lifetime fees) minusdFeesAcc(slot's feeAcc snapshot). TheliquidityContributionis the slot'sallocationdivided by total liquidity (xLiquidoryLiquid). ThefeeShareiscontributedFeesmultiplied byliquidityContribution, capped at available fees. - Depositor Changes: Allows the original depositor to transfer ownership of their slot.
- Slot Creation: Each deposit uses a unique slot, old slots cannot be reused.
- Security: Uses
onlyValidListingmodifier for listing validation viaCCAgentisValidListing. EmploysnonReentrantto prevent reentrancy attacks. Failures trigger events for graceful degradation.