Functions
registerSettlement()
Registers expected deposits for a settlement. Called by the settlement engine after compliance clears.- Token address (the ERC-20 or ERC-3643 token to deposit)
- Amount expected
- Depositor address (must match the registered party)
depositLeg()
Deposits tokens for a specific leg. Called by the settlement party (or their custody provider like Fireblocks).- Settlement is registered and not in a terminal state
msg.sendermatches the registered depositor for this leg- The leg has not already been deposited
- Token allowance is sufficient
LegDeposited(bytes32 settlementId, uint256 legIndex, address depositor, uint256 amount)
executeSettlement()
Releases all deposits to their intended recipients. Called by the coordinator (directly or via LayerZero) after the atomicity gate confirms all legs are deposited.- Tokens from the seller’s leg go to the buyer’s wallet
- Tokens from the buyer’s leg go to the seller’s wallet
forcedTransfer() which allows the token’s transfer agent to move tokens between whitelisted addresses.
Emits: SettlementExecuted(bytes32 settlementId)
rollbackSettlement()
Returns all deposited tokens to their original depositors. Called by the coordinator on failure or timeout.SettlementRolledBack(bytes32 settlementId)
claimTimeout()
Permissionless timeout claim. Anyone can call this after the settlement deadline to return deposits.block.timestamp >= timeoutAt and returns all deposits to their original owners. This is a safety mechanism ensuring funds are never locked indefinitely.
Emits: SettlementTimedOut(bytes32 settlementId)
View functions
Events
| Event | When | Data |
|---|---|---|
LegDeposited | A party deposits tokens for a leg | settlementId, legIndex, depositor, amount |
SettlementExecuted | Atomic swap completed | settlementId |
SettlementRolledBack | All deposits returned on failure | settlementId |
SettlementTimedOut | Timeout triggered, deposits returned | settlementId |
Token standards
| Standard | Support | Release mechanism |
|---|---|---|
| ERC-20 | Full | Standard transfer() |
| ERC-3643 | Full | forcedTransfer() via transfer agent role |
Cross-chain mode
In Phase 2 (cross-chain), escrow contracts on remote chains receive instructions from the SettlementCoordinator via LayerZero: The escrow contract on each chain operates independently. It only communicates with the coordinator via LayerZero messages.Security properties
- No admin keys: No KeyStone-controlled withdrawal function
- No upgrade authority: Escrow contracts are designed to be immutable
- Depositor validation: Only the registered party can deposit for each leg
- Atomic execution: All legs release in one transaction or none do
- Permissionless timeout: Anyone can recover funds after the deadline
- No custody risk: KeyStone never controls deposited funds