本文档介绍了 ComposableCoW 的架构设计,旨在提高 CoW Protocol 与 Safe 的互操作性,实现更高效的条件订单处理。
ComposableCoW
架构以下原则已应用于架构设计中:
n
阶的创建/替换/删除操作,具有 O(1)
的效率。calldata
传递。Safe
的一等公民,反之亦然 🐮🔒。GPv2Order
都不能被多次执行。加粗条件订单加粗:表示 0..n
个离散订单的逻辑结构。
加粗离散订单加粗:提交给 CoW 协议 API 的订单(即 GPv2Order.Data
),即 CoW 协议定义的单个 orderUid
。
为了本文档的目的,如果未指定订单的加粗类型加粗,则应假定为加粗条件订单加粗。
目前,与 CoW 交互的加粗智能合约加粗需要:
GPv2Settlement.setPreSignature(orderUid)
(API 签名类型为“预签名”);或者isValidSignature(bytes32,bytes)
(API 签名类型为“eip1271”),其中传递的 bytes32
参数是 GPv2Order.Data
的 EIP-712 摘要。目前,订单一直在链上产生新的合约,需要处理基本的 retrieve
/ cancel
功能来恢复资产。Safe
已经为此目的提供了最好的解决方案,所以我们不要重新发明轮子!🛞
此修订后的架构旨在实现的使用案例包括:
GAT
) 订单(离散订单,以开始时间为条件)。n x GAT
订单来实现 TWAP。n x conditional orders
)架构分析是从使用
Safe
与 CoW 协议的角度进行的。
所有 CoW 协议的离散订单都经过“签名”。签名方法包括:
EOA Only
EOA Only
Contract Only
Contract & EOA
GPv2Settlement
EIP-712
Eth-Sign
EIP-1271
Pre-Sign
通过 Safe
进行签名是通过 approvedHash
或 threshold
签名完成的,如下所示:
delegatecall SigningLib
manual assembly of signatures
Safe
approvedHash - tx
threshold - gasless
因此,当使用 Safe
时:
orderUid
)必须由 Safe
单独批准/签名。Safe
的角度来看,只有 threshold
类型的 EIP-1271 签名是 gasless 的。结果是用户体验受到了极大的限制。
ComposableCoW
该合约实现了 ISafeSignatureVerifier
,旨在与 ExtensibleFallbackHandler
一起使用 - Safe
的一个新的 FallbackHandler
。ExtensibleFallbackHandler
为 safe
提供了第三种 EIP-1271 验证方法 - 它允许将 EIP-712 域委托给自定义合约。
因此,ComposableCoW
将处理 GPv2Settlement.domainSeparator()
EIP-712 域的所有 EIP-1271 签名。
因此,ComposableCoW
负责:
owner
的 n
个条件订单的离散订单验证路由。每个条件订单在清算时都具有以下属性/数据,具体取决于实现:
handler
- 将验证条件订单参数的合约。salt
- 允许同一类型和数据的多个条件订单。staticData
- 条件订单创建的所有 加粗离散加粗 订单都可以使用的数据。offchainData
- 从链下加粗可选地加粗 提供给 加粗离散加粗 订单的数据。由于所有这些(不包括 offchainData
)在创建时都是已知的,因此它们被组合在结构体 ConditionalOrderParams
中:
struct ConditionalOrderParams {
IConditionalOrder handler;
bytes32 salt;
bytes staticData;
}
ConditionalOrderParams
具有以下属性:
H(ConditionalOrderParams)
必须 是唯一的。salt
应该 设置为密码学上安全的随机值,以确保 (1)。verify
之前,都由 ComposableCoW
验证。offchainInput
具有以下属性:
ComposableCoW
验证。验证是 handler 的责任。警告:订单实现必须验证 offchainInput
!
mapping (address => bytes32) roots; // For Merkle roots (n conditional orders)
mapping (address => mapping (bytes32 => bool)) singleOrders; // Per conditional order (if not in Merkle root)
CoW 协议订单清算执行路径(假设 safe
):
call: isValidSignature
delegatecall: isValidSignature
call: isValidSignature
call: isValidSafeSignature
call: verify
GPv2Settlement
SafeProxy
SafeSingleton : FallbackManager
ExtensibleFallbackHandler : SignatureVerifierMuxer
ComposableCoW
IConditionalOrder
实现 ISafeSignatureVerifier
意味着 ComposableCoW
将实现 isValidSafeSignature
:
function isValidSafeSignature(
Safe safe,
address sender,
bytes32 _hash,
bytes32 domainSeparator,
bytes32, // typeHash
bytes calldata encodeData,
bytes calldata payload
) external view override returns (bytes4 magic);
encodeData
:在清算期间被验证的订单的 ABI 编码的 GPv2Order.Data
。payload
:abi.encode(bytes32[] proof, ConditionalOrderParams params, bytes offchainInput)
typeHash
被忽略,因为 CoW 协议只有一个 typeHash
(GPv2Order.Data
)。以下安全约束由 ComposableCoW
强制执行:
ConditionalOrderParams
必须 获得 owner
授权才能使用。isValidSafeSignature
valid
invalid
valid
invalid
valid
invalid
Extensible Fallback Handler: SignatureVerifierMuxer
Check Authorisation: MerkleRoot
Proof & ConditionalOrderParams
IConditionalOrder:verify
Check Authorisation: Single Order
ConditionalOrderParams
Revert
Return ERC1271 Magic
叶子: H(ConditionalOrderParams)
,即 H(handler || salt || data)
属性:
n
个条件订单的 O(1)
gas 效率。方法:
调用者将 abi.encode(bytes32[] proof, ConditionalOrderParams params)
作为 payload
参数传递,其中 proof
包含 Merkle Tree 证明。
授权:
如果 proof
断言 节点 H(params)
是 merkle tree roots[owner]
的成员,则订单 O 为有效。
属性:
n
x SSTORE
)。方法:
调用者将 abi.encode(bytes32[] proof, ConditionalOrderParams params, bytes offchainInput)
作为 payload
参数传递,其中 proof
是零长度的 bytes32[]
。
授权:
如果 singleOrders(owner, H(params)) == true
,则订单 O 有效。
owner
使用适用的 setter 方法,具体取决于他们希望如何指定订单。
owner
调用 setRoot(bytes32 root, Proof calldata proof)
setter 方法。
struct Proof {
uint256 location;
bytes data;
}
root
:条件订单的 Merkle Tree(叶子 = H(params)
)。proof
:瞭望塔可能会从中找到证明的位置。私有: Proof({location: 0, data: bytes("")})
- 没有证明可供瞭望塔使用。
日志: Proof.location = 1
并且 Proof.data = abi.encode(bytes[] order)
,其中 order = abi.encode(bytes32[] proof, ConditionalOrderParams params)
。
当设置新的 merkle root 时,会发出 MerkleRootSet(address indexed owner, bytes32 root, Proof proof)
。
注意: ComposableCoW
将不验证通过 proof
参数传递的证明数据以进行 setRoot
。验证/确认这一点是客户端和瞭望塔的责任。
注意: Proof.location
有意未设置为 enum
,以便将来可以集成其他证明位置,包括但不限于 Swarm、Waku、IPFS 等。
owner
调用相应的 setter 方法:
create(ConditionalOrderParams params, bool dispatch)
如果 owner
想要公开订单,则将 dispatch
设置为 true
,并且订单创建将导致发出 ConditionalOrderCreated(address indexed owner, ConditionalOrderParams params)
。
remove(bytes32 orderHash)
要删除订单,请从初始的 ConditionalOrderCreated
设置 orderhash = H(params)
。不发出任何事件,因为订单已失效(任何试图截取离散订单的瞭望塔都会看到 getTradeableOrder()
将 revert)。
默认是为条件订单使用 Factory
基本模式,其中基于订单的属性,它能够生成可交易的订单(GPv2Order.Data
)。
为此,订单实现了 IConditionalOrderFactory
接口。遵循此模式,开发人员必须确保:
H(IConditionalOrderFactory.getTradeableOrder(owner,sender,params,offchainInput)) == _hash
其中 _hash
是传递到 isValidSignature()
调用中的 _hash
。
这些实现了顶级的 IConditionalOrder
接口,该接口仅提供原始的 verify
方法,并且不允许生成订单。
由于这些订单没有被 CoW 协议 API 自动索引,因此需要某种方法将它们转发给 CoW 以包含在批处理中。这是通过引用 ComposableCoW
发出的事件来完成的:
ConditionalOrderCreated(address indexed owner, ConditionalOrderParams params)
MerkleRootSet(address index owner, bytes32 root, Proof proof)
加粗发出加粗 上述方法的合约应提供一种方法:
function getTradeableOrderWithSignature(
address owner,
bytes32[] proof,
ConditionalOrder params,
bytes offchainInput
) external view (GPv2Order.Data memory, bytes memory signature);
在 ComposableCoW
的上下文中,这将:
owner
是否是 safe
,并为 EIP-1271 signature
提交给 CoW 协议提供 SignatureVerifierMuxer
适当的格式。safe
,则根据 abi.encode(domainSeparator, staticData, offchainData)
格式化 EIP-1271 signature
。ComposableCoW
将:
IERC165
检查订单类型是否支持离散订单生成(即 IConditionalOrderFactory
)(如果不支持,则 revert
,允许瞭望塔修剪无效的受监控条件订单)。getTradeableOrder
以获取 GPv2Order.Data
注意: 取消/删除订单时无需发出这些事件,因为调用 getTradeableOrderWithSignature
将产生一个带有自定义 error
的 revert
,表明该订单在当前状态下永远无效。
IConditionalOrder
这是条件订单的根级别接口,实现了:
function verify(
address owner,
address sender,
bytes32 hash,
bytes32 domainSeparator,
bytes calldata staticInput,
bytes calldata offchainInput
GPv2Order.Data calldata order,
) external view;
注意: 如果指定的参数与有效订单不对应,则 verify
方法必须 revert
。
IConditionalOrderFactory
通过实现 ERC165
和:
function getTradeableOrder(
address owner,
address sender,
bytes calldata staticInput,
bytes calldata offchainInput
) external view returns (GPv2Order.Data memory);
允许生成离散订单以提交给 CoW 协议。
- 原文链接: hackmd.io/pmZX_qT2Q1yw59...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!