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
MFPListingTemplate
andCCLiquidityTemplate
viaMFPListingLogic
andCCLiquidityLogic
using_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
,allListedTokens
mapped to TokenA / TokenB token pairs and lister details. - Initialization: Configures contracts with routers, tokens via
_initializeListing
,_initializeLiquidity
. - Lister Management: Supports
transferLister
and paginated queries (getListingsByLister
,queryByAddressView
) withmaxIterations
. - Validation: Ensures non-zero addresses, unique token pairs, emits
ListingCreated
,ListingRelisted
,ListerTransferred
.
- MFPListingLogic: Deploys listing contracts via
deploy
with 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 callsetGlobalizerAddress
if 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
resetRouters
on theMFPListingTemplate
andCCLiquidityTemplate
, 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, butgetListing
and 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 affectsgetListing
getLister
,listingsByLister
,allListings
,allListedTokens
. - Initialization: Configures listings with oracle parameters (
oracleAddress
,oracleFunction
,oracleBitSize
,oracleIsSigned
,oracleDecimals
) andbaseToken
via_initializeListing
. - Oracle Integration: Sets
baseOracleParams
for 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 usingmakerPendingOrdersView
and updates order states viaccUpdate
and transfers principal viatransactToken
ortransactNative
. -
CCLiquidityRouter: Manages deposits - withdrawals - fee claims - and depositor changes on liquidity contract, only uses
liquidityAddressView
on 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 Balance
Example;200 / 100 = 2
Buy 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.05
When 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.439024390243902
would be moved if settled at current price, this would push the price to;205÷97.56097560975609 = 2.10125
Which 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.379535990481856
TokenB not2.439024390243902
and 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 viaccUpdate
withBuyOrderUpdate
orSellOrderUpdate
structs, 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
ICCLiquidityTemplate
vialiquidityAddressView
to fetchxLiquid
,yLiquid
,xFees
, andyFees
, enabling additional data queries viaCCDexlytan
. - Historical Data: Maintains
HistoricalData
array and_dayStartIndices
for tracking price, balances, and volumes at midnight timestamps, created viaccUpdate
withHistoricalUpdate
struct. Historical volumes are updated withinBuyOrderUpdate
orSellOrderUpdate
usingpending
andamountSent
changes. - Security: Restricts updates to validated routers (
routers
mapping,routerAddressesView
) viaICCAgent.getRouters
. Uses try-catch for external calls, emitting events (OrderUpdated
,BalancesUpdated
,UpdateFailed
) for graceful degradation. - Token Registry and Globalizer: Supports
TokenRegistry
for global balance storage andGlobalizer
for 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
MFPListingTemplate
in 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/USD
35 / 3500 = 0.01
This means 1 LINK is equal to 0.01 XAU. Buy orders convert tokenB to TokenA as;Order Amount / price
Example;10 XAU / 0.01 = 1000 LINK
Whereas sells convert TokenA to TokenB;Order Amount * price
Example;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
ccUpdate
to adjust liquid balance (xLiquid
/yLiquid
) and liquidity slot data during deposit.- Calls transfer functions (
transactToken
/transactNative
) during withdrawal, withccUpdate
for 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 toSlot
structs (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
/ySlot
details (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
recipient
field for user supplied order recipient. - Validation: Uses
onlyValidListing
modifier to verify listing viaCCAgent
, ensuring non-zero liquidity address and distinct token pairs. - Payout Settlement: Fetches active payout IDs from
CCLiquidityTemplate
usingactiveLongPayoutsView
andactiveShortPayoutsView
, settles payouts using liquidity balance viatransactToken
ortransactNative
, updates liquidity balances usingccUpdate
atCCLiquidityTemplate
. - Data Queries: Retrieves maker orders via
makerPendingOrdersView
, order details viagetBuyOrderCore
,getSellOrderCore
,getBuyOrderAmounts
,getSellOrderAmounts
, and token details viatokenA
,tokenB
,decimalsA
,decimalsB
onCCListingTemplate
.
- Uses
nonReentrant
modifier to prevent reentrancy. - Peng
ReentrancyGuard
usesreentrancyException
withaddRenterer
andremoveReenterer
restricted to contract owner. - Emits
TransferFailed
for 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 withstep
andmaxIterations
(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
/transactNative
for transfers, checking post-transfer balances. - Update Application: Applies updates via
ccUpdate
withBuyOrderUpdate
/SellOrderUpdate
structs. Updatespending
,filled
,amountSent
, andstatus
(2 for partial, 3 for filled) viaccUpdate
. - Historical Data: Creates
_createHistoricalEntry
for price/volume analytics. - Security: Uses
nonReentrant
and 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
swapAmount
to determine the max amount that can be swapped within the price bounds. IfswapAmount
is 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
maxIterations
orders 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
CCLiquidityTemplate
usingccUpdate
. -
Liquidity Updates: Transfers principal to liquidity contract and adjusts
xLiquid
/yLiquid
using normalized amounts (1e18 decimals) to ensure consistency. -
Historical Data: Creates
HistoricalUpdate
entries before processing orders, capturing currentvolumeBalances
andprices(0)
fromMFPListingTemplate
for accurate tracking. -
Security: Uses
nonReentrant
modifier to prevent reentrancy. Validates listings viaonlyValidListing
modifier. -
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
volumeBalances
function inMFPListingTemplate
is 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
makerPendingOrdersView
returns an empty array orstep
exceeds the array length, the contract emits aNoPendingOrders
event and returns without reverting. - Insufficient Liquidity: If
volumeBalances
indicates zeroxBalance
(for sell orders) oryBalance
(for buy orders), it emits anInsufficientBalance
event and exits without processing, avoiding a revert. - Invalid Pricing: If the order's pricing (
impactPrice
) is outsidemaxPrice
/minPrice
, it emits aPriceOutOfBounds
event, skips the order, and continues processing others, ensuring batch operations proceed. - Zero Pending Amount: If an order's
pendingAmount
is zero,_processOrderBatch
skips it without reverting, continuing to the next order.
- Null Impact: Because all orders settled using
MFPLiquidRouter
transfer 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/yLiquid
the 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
compensationAmount
during 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 statedcompensationAmount
to a relative value in the allocation token. Using the current price fromCCListingTemplate
usingprices
. 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
contributedFees
asx/yFeesAcc
(total lifetime fees) minusdFeesAcc
(slot's feeAcc snapshot). TheliquidityContribution
is the slot'sallocation
divided by total liquidity (xLiquid
oryLiquid
). ThefeeShare
iscontributedFees
multiplied 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
onlyValidListing
modifier for listing validation viaCCAgent
isValidListing
. EmploysnonReentrant
to prevent reentrancy attacks. Failures trigger events for graceful degradation.