You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If you aren't interested in the order structure in Solidity, skip to [From Vm](#from-vm). For API documentation, refer to the [API Swagger documentation](https://catalyst-order-server-0140d799e2f7.herokuapp.com/api
11
+
If you aren't interested in the order structure in Solidity, skip to [From VM](#from-evm). For API documentation, refer to the [API Swagger documentation](https://catalyst-order-server-0140d799e2f7.herokuapp.com/api
12
12
).
13
13
14
-
Catalyst is ERC-7683-ish compatible. The implementation differs in 2 ways:
14
+
Catalyst is [ERC-7683](https://www.erc7683.org)* compatible. *The implementation differs in 2 ways:
15
15
16
-
1. A Catalyst Order Key is returned on `initiate(...)`. For implementations that wants to verify that an order was correctly collected, this adds an option for further data validation. This change is compatible with ERC-7683 since it does not change function signatures and ERC-7683 specifies that the function has no return.
17
-
2.In the struct `Output` both the element `token` and `recipient`are encoded as `bytes32` instead of `address`. Solidity ABI encodes structs such that they fill 32 bytes. As a result, all returned objects of `ResolvedCrossChainOrder` remains compatible with implementations that assumes these are `address` (except these values are truncated).
16
+
1. A Catalyst [OrderKey](https://github.com/catalystdao/cross-cats/blob/7e07281eef10ffadc10f9f75eb42d1c2419224ca/src/interfaces/Structs.sol#L41-L65)is returned on `initiate(...)`. For implementations that wants to verify that orders were correctly collected, this adds options for further data validation. This change is compatible with ERC-7683 since it does not change any function signatures and ERC-7683 specifies that the function has no return.
17
+
2.ERC-7683 defines the 2 elements of `Output`, `token` and `recipient`to be type `address`. The type of both elements have been changed to `bytes32`. Solidity ABI encoding encodes structs elements such that they fill 32 bytes. As a result, all returned objects of `ResolvedCrossChainOrder` remains compatible with implementations that assumes these are `address` (except these values are truncated).
18
18
19
-
There are 3 order structures in play.
20
-
1. CrossChainOrder is a generic **input** order with an ERC-7683 compatible structure. Importantly, orderData contains the secret sauce and surely differs between ERC-7683 supporting implementations.
21
-
2. ResolvedCrossChainOrder is a **output** description that roughly describes the value of a cross-chain order at a specific moment in time. It is ERC-7683 compliant* and allows solvers to easily compare resolution of order across protocols.
22
-
3. Catalyst Order Keys are used to keep track of a Catalyst order through its **lifetime**. It contains Catalyst specific context and describes orders in depth. The hash of this struct is used to index the state progress of orders.
19
+
Cross Cats uses 3 order structures:
20
+
1.[CrossChainOrder](https://github.com/catalystdao/cross-cats/blob/7e07281eef10ffadc10f9f75eb42d1c2419224ca/src/interfaces/ISettlementContract.sol#L6-L27) is a generic **input** order with an ERC-7683 compatible structure. Importantly, orderData contains the secret sauce and surely differs between ERC-7683 supporting implementations.
21
+
2.[ResolvedCrossChainOrder](https://github.com/catalystdao/cross-cats/blob/7e07281eef10ffadc10f9f75eb42d1c2419224ca/src/interfaces/ISettlementContract.sol#L29-L52) is a **quote** description that describes the value of a cross-chain order at a specific moment in time. It is ERC-7683 compliant* and allows solvers to easily compare resolution of order across protocols.
22
+
3. Catalyst [OrderKey](https://github.com/catalystdao/cross-cats/blob/7e07281eef10ffadc10f9f75eb42d1c2419224ca/src/interfaces/Structs.sol#L41-L65) are used to keep track of a Catalyst order through its **lifetime**. It contains Catalyst specific context and describes orders in depth. The hash of this struct is used to index the state progress of orders.
23
23
24
24
The generic CrossChainOrder can be seen below. `CrossChainOrder.orderData` is an ABI encoded order struct.
25
25
```solidity
@@ -34,8 +34,9 @@ struct CrossChainOrder {
34
34
}
35
35
```
36
36
37
-
Currently, Cross-Cats supports 2 order structs:`LimitOrderData` and `DutchOrderData` for many inputs (same chain) to many outputs (different chains) and Dutch Auctions (1 to 1), respectively.
37
+
Currently, Cross-Cats supports 2 order structs:
38
38
```solidity
39
+
/// @notice Supports many inputs (same chain) to many outputs (different chains)
39
40
struct LimitOrderData {
40
41
uint32 proofDeadline;
41
42
uint32 challengeDeadline;
@@ -47,7 +48,7 @@ struct LimitOrderData {
47
48
Input[] inputs;
48
49
Output[] outputs;
49
50
}
50
-
51
+
/// @notice Supports Dutch Auctions on both input and output (1 to 1).
51
52
struct DutchOrderData {
52
53
bytes32 verificationContext;
53
54
address verificationContract;
@@ -65,11 +66,11 @@ struct DutchOrderData {
65
66
Output output;
66
67
}
67
68
69
+
// With the input and output struct defined as:
68
70
struct Input {
69
71
address token;
70
72
uint256 amount;
71
73
}
72
-
73
74
struct Output {
74
75
bytes32 token;
75
76
uint256 amount;
@@ -78,13 +79,12 @@ struct Output {
78
79
}
79
80
```
80
81
81
-
Users will generate these order descriptions and then sign them with Permit2, generating an approval & order description with a single signature.
82
-
83
-
82
+
Users will generate a `CrossChainOrder` with the appropriate order data and sign them with Permit2, generating an approval & order description with a single signature. The signed struct with be a new struct where `
83
+
orderData` will be of the order type struct.
84
84
85
-
## From VM
85
+
## From EVM
86
86
87
-
Cross Cats has directionality. That means the ways orders are initiated depends on the inputs chain (where the user is swapped out of). In the current iteration, there are 2 important origin types: EVM and Bitcoin. In the future, all virtual machine chains will generally be supported in a similar manner but non-VM chains behave slightly different.
87
+
Cross Cats has directionality. That means the ways orders are initiated depends on the initiating chain (where the user is swapping out of). In the current iteration, there are 2 important origin types: EVM and Bitcoin. In the future, all virtual machine chains (including EVM) will generally be initiated in a similarly and all non-VM chains (including Bitcoin) will be initiated in a similarly but different from VM chains.
88
88
89
89
On VM chains, assets can be pulled from the user through approvals. This is not possible on non-VM chains. As a result, the order of operations is slightly different. The following section describes orders originating from a VM chain, the section [From Bitcoin](#from-bitcoin) describes orders originating from Bitcoin.
90
90
@@ -194,13 +194,13 @@ Unlike the API endpoint, orders delivered over the websocket connected are not f
194
194
195
195
### Evaluate Orders
196
196
197
-
After fetching an order, it is expected that the solver evaluates the order. There are several helpful context pointers in the returned order, like `getOrderData.quote` which returns the price context used to price the inputs and outputs. If you trust the order server, it is sufficient to validate the quote and check that the solver supports the origin chain: `getOrderData.order.originChainId` and the outputs chains: `getOrderData.order.orderData.outputs[...].chainId`. These parameters will always be present.
197
+
After fetching an order, it is expected that the solver evaluates the order. There are several helpful context pointers in the returned order, like `getOrderData.quote` which returns the price context used to price the inputs and outputs. If you trust the order server, it is sufficient to validate the quote and check that the solver supports the origin chain: `getOrderData.order.originChainId` and the outputs chains: `getOrderData.order.orderData.outputs[...].chainId` along with their respective tokens `input|output[].token` These parameters will always be present regardless of order type.
198
198
199
199
Some orders may be exclusive. If `getOrderData.order.orderData.verificationContract` is defined and not `address(0)`, it will be exclusive until `getOrderData.order.orderData.slopeStartingTime`. In these cases, if they aren't exclusive to you wait until `getOrderData.order.orderData.slopeStartingTime` before initiating the order.
200
200
201
201
### Initiate Orders
202
202
203
-
After fetching and validatnig an order, it has to be submitted on-chain. Catalyst Orders arrive signed: `getOrderData.signature`. The signature is multi-use. It is a permit2 signature and allows our contracts to pull the submittor's tokens and ensures that the user approves the order. If orders are not exclusive, they are initiated on a first come first serve basis.
203
+
After fetching and validatnig an order, it has to be submitted on-chain. Catalyst Orders arrive signed: `getOrderData.signature`. The signature is multi-purpose. It is a permit2 signature and allows our contracts to pull the submittor's tokens and ensures that the user approves of the order. If an order is not exclusive, it will be initiated on a first come first serve basis.
204
204
205
205
<TabssyncKey="lang">
206
206
<TabItemlabel="Typescript">
@@ -228,7 +228,7 @@ async function initiateOrder() {
If `fillerData` is not provided, the input (user provided assets) will be sent to the caller. This is likely desired and as such there may be no further need to customize `fillerData`.
293
292
294
-
However, if you want to send the input to another address OR enable underwriting you need to use customized `fillerData`. Currently only 1 custom version is supposed, v1. It is structured by 1 version byte (`0x01`), `fillerAddress`, `orderPurchaseDeadline`, and `orderDiscount`:
295
-
-`fillerAddress`can be set to another address and indicates the (recipient of input assets)
296
-
-`orderPurchaseDeadline` allows someone else to buy the order before this time. Buy here means paying all of the inputs assets & potential collateral to you.
297
-
-`orderDiscount` gives buyers a small discount on the inputs. Is of `2**16-1`. To provide 1% discount: `0.01*(2**16-1)=655`. For chains with slow blocks (Bitcoin) this can be used to pay the solver using only 0-1 confirmations while assuring the user that they get high finality (6 confirmations).
293
+
However, if you want to send the input to another address OR enable underwriting you need to use customized `fillerData`. Currently only 1 custom version is supported: v1. It is structured by 1 version byte (`0x01`), `fillerAddress`, `orderPurchaseDeadline`, and `orderDiscount`:
294
+
-`fillerAddress`is the recipient of the input assets & collateral.
295
+
-`orderPurchaseDeadline` allows someone else to buy the order before this time. Buy here means paying all of the inputs assets & collateral to `fillerAddress`.
296
+
-`orderDiscount` gives buyers a small discount on the inputs. Is of `2**16-1`. To provide 1% discount: `0.01*(2**16-1)=655`. For chains with slow blocks (Bitcoin) this can be used to pay the solver after 0-1 confirmations while ensuring the user that they get high finality (3-6 confirmations).
To identify whether an order contains a Bitcoin transaction, check the output token: `getOrderData.order.orderData.outputs[].token`. If the output is Bitcoin, the following must hold:
423
-
- The first 12bytes can be anything and are not read.
424
-
- The 13'th byte (or 20'th from right) must be 0xBB.
425
-
- Byte 14 through 30 must be 0.
426
-
- Byte The 2bytes31and32 contains an address version identifier. Decode as uint16.
422
+
- The first 30bytes should be equal to `0x000000000000000000000000BB0000000000000000000000000000000000`. The 13'th byte is `0xBB`.
423
+
- The 31'th byte is reserved and not checked.
424
+
- The 32'th byte contains an address version identifier. Decode as uint8.
427
425
428
-
If the transaction is to Bitcoin, the address (`getOrderData.order.orderData.outputs[].recipient`) will contain the relevant hashor witness.
426
+
If the transaction is to Bitcoin, the address (`getOrderData.order.orderData.outputs[].recipient`) will contain the relevant destination hashor witness which isnot the address!
429
427
430
428
<table>
431
429
<thead>
@@ -486,25 +484,28 @@ If the transaction is to Bitcoin, the address (`getOrderData.order.orderData.out
486
484
487
485
The below tutorials assume that you are implementing this from the perspective of a solver. As a result, you are interested in converting an expected output script into a Bitcoin address that can be provided to your wallet.
488
486
489
-
-**P2PKH**. The recipient is the public key hash. The scripthash needs to be encoded with [Base58Check](https://rosettacode.org/wiki/Base58Check_encoding). Select the first 20bytesand prepend with00. Encode with Base58Check.
487
+
-**P2PKH**. The recipient is the public key hash. The public keyhash needs to be encoded with [Base58Check](https://rosettacode.org/wiki/Base58Check_encoding). Select the first 20bytesand prepend with00. Encode with Base58Check.
490
488
-**P2SH**. The recipient is the script hash. The script hash needs to be encoded with [Base58Check](https://rosettacode.org/wiki/Base58Check_encoding). Select the first 20bytesand prepend with05. Encode with Base58Check.
491
489
-**P2WPKH**. The recipient is the witness. The witness needs to be encoded with [Bech32](https://github.com/bitcoinjs/bech32). Select the first 20bytes. Encode with Bech32. Prepend with bc1q.
492
490
-**P2WSH**. The recipient is the witness hash. The witness hash needs to be encoded with [Bech32](https://github.com/bitcoinjs/bech32). Select the first 32bytes. Encode with Bech32. Prepend with bc1q.
493
491
-**P2WTR**. The recipient is the witness hash. The witness hash needs to be encoded with [Bech32m](https://en.bitcoin.it/wiki/BIP_0350#Bech32m). Select the first 32 bytes. Encode with Bech32m. Prepend with bc1p.
494
492
495
-
Once the address is generate, make a transaction that has an **exact** output that matches any outputs from the initiated order. There is no limit as to how the transaction is organised, it may have any inputs and outputs aslongas one output matched exactly the one described by the order's output. This allows for transaction flexibility like batch filling, consolidation, and more.
493
+
Nested witness outputs are **P2SH**.
494
+
495
+
Once the address is generated, make a transaction that has 1**exact** output that matches the relevant output from the initiated order. There is no limit as to how the transaction is organised, it may have any inputs and outputs aslongas one output matched exactly the one described by the order's output. This allows for transaction flexibility like batch filling, consolidation, and more.
496
496
497
497
## From Bitcoin
498
498
499
-
While Bitcoin has scripts, Bitcoin scripts are only contains spending conditions so unlike a VM chain, we can't pull funds from the user after a signed message. As a result, the order flow is flipped and the solver signed the VM order.
499
+
While Bitcoin has scripts, Bitcoin scripts only contains spending conditions so unlike a VM chain, we can't pull funds from the user after a signed message. As a result, the order flow is flipped and the solver signed the VM order.
500
+
While it is technically possible to create unique conditional deposits addresses, no wallets support custom scripts.
500
501
501
502
#### Encoding a Bitcoin Address
502
503
503
-
Your solver needs to be able to generate a Bitcoin deposit address. It is technically possible to use the same address for every single order. If you do this, it is very important that the amounts are unique for every single order. It is recommended to use different addresses for every order. Bitcoin does not charge extract to collect UTXOs from different addresses.
504
+
Your solver needs to be able to generate a Bitcoin deposit address. It is technically possible to use the same address for every single order. If you do this, it is very important that the amounts are unique for every single order. It is recommended to use different addresses for every order. Bitcoin does not charge extra to collect UTXOs from different addresses.
504
505
505
506
The Bitcoin address is encoded in2 fields: `token`and`address`. The token field is used to block tokens from filling Bitcoin orders and to encode the address version. See this [table](#bitcoin-deliveries) for converting address types to versions.
506
507
507
-
The `address`is used to encode either the public key hash, script hash, or witness hash. The table mentioned above contains the encoding schemes for various Bitcoin address versions. Hashes of 20bytes (P2PKH, P2SH, andP2WSH) should be padded with0s on the right side. (`0xabcdef...00000`)
508
+
The `address`is used to encode either the public key hash, script hash, or witness hash. The table mentioned above contains the encoding schemes for various Bitcoin address versions. Hashes of 20bytes (P2PKH, P2SH, andP2WPKH) should be padded with0s on the right side. (`0xabcdef...00000`)
Once the signedOrder is sent & it correctly matches the expected quote, the vast vast majority of orders will be filled.
559
+
560
+
TODO: The UI may respond back with a transaction hash.
558
561
559
562
## Prove Orders (WIP)
560
563
561
-
If a Solvers' orders get challenged, they need to prove delivery. In exchange for these proofs, Solvers collect the collateral provided by Challengers.
564
+
If Solvers' orders get challenged, they need to prove delivery. In exchange for these proofs, Solvers collect the collateral provided by Challengers.
562
565
563
566
Initially, Cata Labs will prove every single order for completeness.
0 commit comments