or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing
xxxxxxxxxx
ComposableCoW
ArchitectureThe following principles have been employed in the architectural design:
O(1)
efficiency forn
order creation / replacement / deletion.calldata
.Safe
and vice-versa 🐮🔒.Assumptions
GPv2Order
can be filled more than once.Definitions
Conditional Order: A logical construct representing
0..n
discrete orders.Discrete Order: An order submitted to the CoW Protocol API (ie.
GPv2Order.Data
), ie. a singleorderUid
as defined by CoW Protocol.For the purposes of this documentation, if the type of order is not specified, it shall be assumed to be a conditional order.
Use cases
Currently a smart contract interacting with CoW is required to either:
GPv2Settlement.setPreSignature(orderUid)
(API signing type "pre-sign"); orisValidSignature(bytes32,bytes)
(API signing type "eip1271"), where thebytes32
parameter passed is the EIP-712 digest of theGPv2Order.Data
.Presently orders have been spawning new contracts on chain, necessitating the handling of basic
retrieve
/cancel
functionality to recover assets.Safe
already provides a best-in-class for this purpose, so let's not reinvent the wheel! 🛞Use cases that this revised architecture seeks to enable include:
GAT
) orders (discrete orders, conditional on a starting time).n x GAT
orders.n x conditional orders
)Current Architecture
All CoW Protocol discrete orders are "signed". The signing methods are:
Signing via
Safe
is done viaapprovedHash
orthreshold
signatures, as follows:Therefore, when using
Safe
:orderUid
) must be approved/signed individually by theSafe
.threshold
type EIP-1271 signatures are gasless from a CoW Protocol andSafe
perspective.The result is a significantly constrained user experience.
ComposableCoW
This contract implements
ISafeSignatureVerifier
, designed to be used withExtensibleFallbackHandler
- a newFallbackHandler
forSafe
.ExtensibleFallbackHandler
provides a third method of EIP-1271 validation forsafe
- it allows delegating an EIP-712 domain to a custom contract.ComposableCoW
therefore will process ALL EIP-1271 signatures for theGPv2Settlement.domainSeparator()
EIP-712 domain.Therefore,
ComposableCoW
is responsible for:n
conditional orders perowner
.Order Data
Each conditional order has the following properties/data available at settlement depending on implementation:
handler
- the contract that will verify the conditional order's parameters.salt
- allows for multiple conditional orders of the same type and data.staticData
- data available to ALL discrete orders created by the conditional order.offchainData
- data optionally provided from off-chain to a discrete order.As all of these, excluding
offchainData
are known at creation time, they are grouped together in the structConditionalOrderParams
:ConditionalOrderParams
has the properties:H(ConditionalOrderParams)
MUST be unique.salt
SHOULD be set to a cryptographically-secure random value to ensure (1) WHEN REQUIRED.ComposableCoW
prior to calling an order type'sverify
.offchainInput
has the properties:ComposableCoW
. Validation is the responsibility of the handler.WARNING: Order implementations MUST validate / verify
offchainInput
!Storage
Settlement Execution Path
CoW Protocol order settlement execution path (assuming
safe
):Implementing the
ISafeSignatureVerifier
means thatComposableCoW
will implementisValidSafeSignature
:encodeData
: The ABI-encodedGPv2Order.Data
for the order being validated during a settlement.payload
:abi.encode(bytes32[] proof, ConditionalOrderParams params, bytes offchainInput)
typeHash
is ignored as CoW Protocol only has onetypeHash
(GPv2Order.Data
).Settlement Validity
The following security constraints are enforced by
ComposableCoW
:ConditionalOrderParams
MUST be authorised for use by theowner
.Merkle Root
Leaf:
H(ConditionalOrderParams)
, ie.H(handler || salt || data)
Properties:
O(1)
gas efficiency for add / removen
conditional orders.Methodology:
The caller passes
abi.encode(bytes32[] proof, ConditionalOrderParams params)
as thepayload
parameter whereproof
contains the Merkle Tree proof.Authorisation:
Order O is valid if
proof
asserts that leafH(params)
is a member of merkle treeroots[owner]
.Single Order
Properties:
n
xSSTORE
per order).Methodology:
The caller passes
abi.encode(bytes32[] proof, ConditionalOrderParams params, bytes offchainInput)
as thepayload
parameter whereproof
is a zero-lengthbytes32[]
.Authorisation:
Order O is valid if
singleOrders(owner, H(params)) == true
.Add / Remove Orders
The
owner
uses the applicable setter method depending on how they wish to specify the order.Merkle Root
The
owner
calls thesetRoot(bytes32 root, Proof calldata proof)
setter method.root
: Merkle Tree of conditional orders (leaves =H(params)
).proof
: Where watch towers may locate the proofs from.Private:
Proof({location: 0, data: bytes("")})
- no proofs available to watch-towers.Log:
Proof.location = 1
andProof.data = abi.encode(bytes[] order)
whereorder = abi.encode(bytes32[] proof, ConditionalOrderParams params)
When a new merkle root is set, emits
MerkleRootSet(address indexed owner, bytes32 root, Proof proof)
.NOTE:
ComposableCoW
will NOT verify the proof data passed in via theproof
parameter forsetRoot
. It is the responsibility of the client and watch-tower to verify / validate this.NOTE: The
Proof.location
is intentionally not made anenum
to allow for future extensibility as other proof locations may be integrated, including but not limited to Swarm, Waku, IPFS etc.Single Order
The
owner
calls the respective setter method:create(ConditionalOrderParams params, bool dispatch)
If the
owner
wants to make the order public,dispatch
is settrue
, and the order creation will result in an emission ofConditionalOrderCreated(address indexed owner, ConditionalOrderParams params)
.remove(bytes32 orderHash)
To remove an order, set
orderhash = H(params)
from the initialConditionalOrderCreated
. No event is emitted, as the order is invalidated (any watch tower trying to cut discrete orders will see thegetTradeableOrder()
will revert).Discrete Order Generation
The default is to use a
Factory
base pattern for conditional orders, where based on an order's properties, it is able to generate a tradeable order (GPv2Order.Data
).To do this, an order implements the
IConditionalOrderFactory
interface. Following this pattern, a developer MUST ensure:H(IConditionalOrderFactory.getTradeableOrder(owner,sender,params,offchainInput)) == _hash
Where
_hash
is the_hash
passed into theisValidSignature()
call.Advanced conditional orders
These implement the top-level
IConditionalOrder
interface, which only provides a rawverify
method, and doens't allow for order generation.Watch Towers
As these orders are not automatically indexed by the CoW Protocol API, there needs to be some method of relaying them to CoW for inclusion in a batch. This is done by reference to the events emitted by
ComposableCoW
:ConditionalOrderCreated(address indexed owner, ConditionalOrderParams params)
MerkleRootSet(address index owner, bytes32 root, Proof proof)
The contract that emits the above methods shall provide a method:
In the context of
ComposableCoW
this will:owner
is asafe
, and provide theSignatureVerifierMuxer
appropriate formatting for the EIP-1271signature
submission to CoW Protocol.safe
, format the EIP-1271signature
according toabi.encode(domainSeparator, staticData, offchainData)
.ComposableCoW
will:IConditionalOrderFactory
) by usingIERC165
(andrevert
if not, allowing the watch-tower to prune invalid monitored conditional orders).getTradeableOrder
on the handler to get theGPv2Order.Data
NOTE: There is no need to emit these events when orders are cancelled / removed as calling the
getTradeableOrderWithSignature
will yield arevert
with a customerror
indicating the order will never be valid with the current state.Interfaces
IConditionalOrder
This is the root-level interface for conditional orders, implementing:
CAUTION: The
verify
method MUSTrevert
if the parameters specified do not correspond to a valid order.IConditionalOrderFactory
Allows for generation of discrete orders for submission to CoW Protocol by implementing
ERC165
and: