Input Settlement
Catalyst currently implements two input settlement schemes:
- TheCompact through
CompactSettlerWithDeposit.sol
- Rhinestone through
CompactSettler.sol
Both TheCompact and Rhinestone are resource locks and thus support first-fill flows. However, Catalyst also supports ordinary flows.
Catalyst provides a base implementation for settlement schemes via BaseSettler.sol
. Alternatively, if possible, CompactSettler.sol
can be forked with less effort.
Default Output
Section titled “Default Output”The default output for settlement schemes is the OutputDescription
:
struct OutputDescription { bytes32 remoteOracle; bytes32 remoteFiller; uint256 chainId; bytes32 token; uint256 amount; bytes32 recipient; bytes remoteCall; bytes fulfillmentContext;}
To check if the encoded output description has been validated, the hashed encoded payload should be sent to the appropriate local oracle using the Validation Layer Interface along with relevant resolution details, such as who the solver was.
CompactSettler
Section titled “CompactSettler”Both Rhinestone and TheCompact work through CompactSettler.sol
. Being able to solve for one allows you to solve the other, except that signature and lock validation differ slightly.
The Compact Settler uses the CatalystCompactOrder
:
struct CatalystCompactOrder { address user; uint256 nonce; uint256 originChainId; uint32 fillDeadline; address localOracle; uint256[2][] inputs; OutputDescription[] outputs;}
Notice that the fillDeadline
is also used as the expiry for the timelock. As a result, when filling outputs of CatalystCompactOrder
, ensure there is sufficient time for validation as well.
The CompactSettler supports five ways to resolve locks once the outputs have been made available for verification by the validation layer:
function finaliseSelf(CatalystCompactOrder calldata order, bytes calldata signatures, uint32[] calldata timestamps, bytes32 solver) external;
function finaliseTo(CatalystCompactOrder calldata order, bytes calldata signatures, uint32[] calldata timestamps, bytes32 solver, address destination, bytes calldata call) external;
function finaliseFor( CatalystCompactOrder calldata order, bytes calldata signatures, uint32[] calldata timestamps, bytes32 solver, address destination, bytes calldata call, bytes calldata orderOwnerSignature) external;
// -- Fallback Finalise Functions -- //
function finaliseTo(CatalystCompactOrder calldata order, bytes calldata signatures, uint32[] calldata timestamps, bytes32[] calldata solvers, address destination, bytes calldata call) external;
function finaliseFor( CatalystCompactOrder calldata order, bytes calldata signatures, uint32[] calldata timestamps, bytes32[] calldata solvers, address destination, bytes calldata call, bytes calldata orderOwnerSignature) external;
Notice that the fallback functions exist to fix orders that have been solved by multiple solvers. This is required because we need to hydrate the OutputDescription
with the solver to check if the output has been filled on the Validation Layer.
The three ways to finalize an intent:
finaliseSelf
: Self-serve, called by the solver with the tokens paid to the solver.finaliseTo
: Self-serve, custom delivery. Called by the solver with the tokens paid to a specific address.finaliseFor
: External finalization with a signed message by the solver designating where assets are to be delivered.
To use external finalization, the struct AllowOpen
must be EIP712 signed:
struct AllowOpen { bytes32 orderId; address originSettler; address destination; bytes call;}
Registering Intents
Section titled “Registering Intents”For how to register intents with Rhinestone, please refer to their documentation.
For TheCompact, CompactSettler.sol
supports BatchClaim
using claim type. The witness is the difference between the BatchClaim
and CatalystCompactOrder
:
struct CatalystWitness { uint32 fillDeadline; address localOracle; OutputDescription[] outputs;}
Sign the BatchClaim
with the CatalystWitness using EIP712 with TheCompact domain separator.
For further integration assistance, refer either to TestCatalyst.t.sol::test_entire_flow
or reach out to the team.
With Deposit
Section titled “With Deposit”When integrating CompactSettler, if the settler uses the withDeposit
extension, you may use the associated deposit function. This allows you to deposit and register an intent at the same time, reducing the number of user interactions by one.
function depositFor(CatalystCompactOrder calldata order, ResetPeriod resetPeriod) external;
When this function is called, the Deposit
event will be emitted for permissionless discovery.
event Deposited(bytes32 orderId, CatalystCompactOrder order);