本文档介绍了 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 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!