技術架構
交易邏輯
概述
TuringMarketFacet
合約實現了二元結果代幣(ERC1155)與抵押資產(ERC20)的原子交換。
它採用混合去中心化交易所模型,由營運商提供鏈下撮合服務,而結算透過簽署訂單訊息的指令在鏈上非託管完成。
圖靈市場支援包含鑄幣/合併操作的撮合,允許互補結果代幣的訂單交叉。
訂單採用 EIP712
標準的結構化資料簽章格式。
此外,合約實現了對稱費用機制。當訂單匹配時,一方作為 maker
另一方作為 taker
,價格改進的收益由 taker
方獲得。
撮合場景
資產定義
A
- ERC1155結果代幣A'
- ERC1155互補結果代幣*C
- ERC20抵押代幣- 以下都是以
A
和A'
單價是 0.5 USDC 為例
註:互補關係指1個結果代幣與1個互補代幣可合併為1個抵押代幣,反之亦可拆分(即*A
** + A'
= C
)。假設結果代幣與抵押代幣具有相同精度單位,以下範例假設**C
**為USDC。
場景1 - 鑄幣交易
- user1 買進 100 個
A
,轉 50 個C
給交易所 - user2 買進 100 個
A'
,轉 50 個C
給交易所 - 交易所鑄幣 100 個
A
給 user1,100 個A'
給 user2
const takerOrder = {
salt: randomId(),
maker: user1,
tokenId: 1, // A' 的 tokenId
tokenAmount: 100 * 10**6,
tokenPriceInPaymentToken: 0.5 * 10**6, // 0.5 USDC, 也有可能為 0,因為用戶市價成交
paymentTokenAddress: '0xxxxx', // USDC 地址
slippageBps: 100, // 允許的滑點,不是 0 則表示使用者在做市價單
deadline: 1672531200, // 過期時間
side: 1, // 1: buy, 2: sell
feeTokenAddress: '', // 手續費代幣地址, USDC 地址或公司幣地址
// 前面是簽署的資料字段
sig: 'xxxxx', // 以上資料的前端簽章結果
// 下面是鏈下計算出來的交易結論
exchangeNftAmount: 100 * 10**6, // 這個 maker 可以拿到多少 NFT
paymentTokenAmount: 100 * 10**6, // 這個 maker 需要支付多少 USDC 作為買入 NFT 的費用
paymentTokenAddress: '0xxxxx', // 支付買 NFT 的費用的代幣地址,即 USDC
// 使用 2 個 fee 欄位來支援多個 fee 代幣,因為有可能用戶的公司幣扣完了,還不夠手續費,就再加上 USDC 來支付
fee1Amount: 123, // 這個 maker 需要支付多少手續費1
fee1TokenAddress: '0xxxxx', // 支付手續費的代幣地址,可能是 USDC,可能是公司幣
fee2Amount: 456, // 這個 maker 需要付多少手續費2
fee2TokenAddress: '0xxxxx', // 支付手續費的代幣地址,可能是 USDC,可能是公司幣
}
const makerOrders = [
{
salt: randomId(),
maker: user2,
tokenId: 2, // A' 的 tokenId
tokenAmount: 100 * 10**6,
tokenPriceInPaymentToken: 0.5 * 10**6, // 0.5 USDC, 也有可能為 0,因為用戶市價成交
paymentTokenAddress: '0xxxxx', // USDC 地址
slippageBps: 100, // 允許的滑點,不是 0 則表示使用者在做市價單
deadline: 1672531200, // 過期時間
side: 1, // 1: buy, 2: sell
feeTokenAddress: '', // 手續費代幣地址, USDC 地址或公司幣地址
// 前面是簽署的資料字段
sig: 'xxxxx', // 以上資料的前端簽章結果
// 下面是鏈下計算出來的交易結論
exchangeNftAmount: 100 * 10**6, // 這個 maker 可以拿到多少 NFT
paymentTokenAmount: 100 * 10**6, // 這個 maker 需要支付多少 USDC 作為買入 NFT 的費用
paymentTokenAddress: '0xxxxx', // 支付買 NFT 的費用的代幣地址,即 USDC
// 使用 2 個 fee 欄位來支援多個 fee 代幣,因為有可能用戶的公司幣扣完了,還不夠手續費,就再加上 USDC 來支付
fee1Amount: 123, // 這個 maker 需要支付多少手續費1
fee1TokenAddress: '0xxxxx', // 支付手續費的代幣地址,可能是 USDC,可能是公司幣
fee2Amount: 456, // 這個 maker 需要付多少手續費2
fee2TokenAddress: '0xxxxx', // 支付手續費的代幣地址,可能是 USDC,可能是公司幣
},
]
matchOrders(takerOrder, makerOrders)
場景2 - 普通交易
- user1 買進 100 個
A
,轉 50 個C
給交易所 - user2 賣出 100 個
A
,從交易所收到 50 個C
場景3 - 合併交易
- user1 賣出 100 個
A
- user2 賣出 100 個
A'
- 交易所合併 user1 和 user2 的 100 個
A
和 100 個A'
為 100 個C
- 交易所將 50 個
C
轉給 user1 - 交易所將 50 個
C
轉給 user2
費用機制
費用從產出資產(收益)收取。對於存在互補關係的二元代幣(即**A
** + A'
= C
),費用必須保持對稱性以維護市場完整性。對稱性意味著以$0.99賣出100個A
代幣與以$0.01買入100個A'
代幣應支付相同的費用價值。
具體規則:
- 買入操作(取得**
A
或A'
**)對產出代幣收取費用 - 賣出作業(取得**
C
**)對產出抵押代幣收取費用
基礎費率(baseFeeRate
)寫入訂單結構,對應兩種代幣價格相等時($0.50和$0.50)的2倍費率。價格偏離中心點時使用以下公式保持對稱性:
usdc手續費 = 基本費率 × min(價格, 1-價格) × 代幣數量
- price = 0.2
- feeBps = 100
- fee = 0.01 * min(0.2, 1-0.2) * 100 = 0.2
- 以$0.99賣出100個
A
代幣: 0.01 * min(0.99, 1-0.99) * 100 = 0.01 (扣除 0.01 個C
作為交易費) - 以$0.01買入100個
A'
代幣 0.01 * min(0.01, 1-0.01) * 100 = 0.01 (扣除 1 個A'
作為交易費)