TXA CSP Data Types

TXA CSP Data Types

This document describes the data types that must be standardized across participants in the DSL.

All data types are defined in Solidity, as this is the format they must take to be properly validated on-chain. Services written in other languages need to ensure proper serialization/deserialization.

Settings

struct Settings {
    address tradeSigningKey;
    address feeRecipient;
    uint256 settlementFeeNumerator;
    uint256 interfaceFeeNumerator;
}

Deposits

struct Deposit {
	address trader;
	address asset;
	address participatingInterface;
	uint256 amount;
	uint256 depositId;
	uint256 chainId;
}

struct DepositUTXO {
	Deposit deposit;
	bytes32 depositHash;
}

Products

struct Asset {
	uint64 assetId;
	uint64 networkType;
	uint64 chainId;
	uint64 extra;
}

struct Product {
	uint256 assetA;
	uint256 assetB;
}

mapping(bytes32 => Product) products;

Orders

The order type is used to trace an executed trade to a signed order (original payload submitted by trader) with matching parameters.

For complex orders that resolve to limit orders, some will have a predetermined range of prices for which the contracts can verify a proper execution price.

For some complex orders, the price cannot be known ahead of time and will be set as 0.

Absolute minimum necessary to represent a limit order:

struct Order {
	Product p;
	bool buyOrSell;
	uint256 size;
	uint256 price;
	address trader;
	uint64 traderId;
	uint64 participatingInterface;
	uint8 v;
	bytes32 r;
	bytes32 s;
}

When a Participating Interface receives an order and moves it through its system, it will apppend additional data to the original signed payload. When the order is included in a trade, it will have this additional data.

For example, the participating interface must assign a timestamp to each order received.

This will also be used when handling complex and contingent orders.

In all cases, an order MUST include the original payload signed by the trader.

Trades

The two orders included in a trade must have attributes that allow one to prove that the parameters of the trade is compatible with each order.

Participating Interface must designate input UTXOs used to fill each side of the trade. Participating Interface must generate output UTXOs.

First input UTXOs in list MUST fill side represented by Order a Last input UTXOs in list MUST fill side represented by Order b

struct TradeParams {
	// Sequence ID
	uint256 tradeId;
	// Participating Interface ID
	uint64 participatingInterface;
	// Trade Parameters
	Order a;
	uint256 timestampA;
	Order b;
	uint256 timestampB;
	Product p;
	uint256 size;
	uint256 price;
}

struct UnsignedTrade {
	TradeParams params;
	// Input and Output UTXOs
	bytes32[] inputUTXOs;
	bytes32[] outputUTXOs;
}

struct Trade {
    UnsignedTrade trade;
    // PI Signature
	uint8 v;
	bytes32 r;
	bytes32 s;
	// Root of tree of all UTXO outputs after appending this trade's outputs
	bytes32 stateRoot;
}

struct TradeSide {
	uint256 amount;
	address asset;
	address trader;
}

struct ValidateTradeResult {
	bool valid;
	// Below only included if valid is false
	FraudInfo fraudInfo;
}

Fraud Proof

struct FraudInfo {
	// TBD
}

ObligationUTXO

When a deposit is used as an input UTXO in a trade, it generates obligation UTXOs that represent the new state of the balance. Each obligation must reference the deposit UTXO from which it originates. Obligations do not require signatures from PI, as the hash of each output obligation is included in each signed Trade.

struct ObligationUTXO {
	address trader;
	uint256 amount;
	uint256 parentTradeId;
	bytes32 parentUtxo;
	// May be optional, as it can be derived using parent
	bytes32 depositUtxo;
	// May be optional, as it can be derived using deposit
	address asset;
	address participatingInterface;
}

SettledUTXO

When a trader requests settlement, the PI must query for all unspent deposits and obligations, marking them as "spent" by creating a child UTXO which can no longer be used as an input.

struct SettledUTXO {
	uint256 settlementId;
	bytes32 parentUtxo;
	// May be optional, as it can be derived using parent
	address trader;
	uint256 amount;
	bytes32 depositUtxo;
	// May be optional, as it can be derived using deposit
	address asset;
	address participatingInterface;
}

Settlement Request

struct SettlementRequest {
        address trader;
        address asset;
        address participatingInterface;
        uint256 chainSequenceId;
        uint256 chainId;
    }

Settlement Block

When SDPs report for settlement, they must include a state commitment that contains all TraderIntent messages signed by the PE for the range of IDs specified in the settlement.

struct SettlementBlock {
	// accumulator of all trades included in the block
	bytes32 tradeRoot;
	//
	// Note that the data rolled up in the commitments below
	// is also contained in the tradeRoot. There may be 
	// 
	// accumulator of all outputs created by trades in this block
	bytes32 outputsRoot;
	// accumulator of all outputs spent by trades in this block
	bytes32 spentOutputsRoot;
	// accumulator of all outputs settled in this block
	bytes32 settledOutputsRoot;
	// accumulator of state root after each trade
	// stateRoot = hash(tradeRoot,outputsRoot,spentOutputsRoot,settledOutputsRoot)
	bytes32 stateRootAccumulator;
}

Settlement Report

struct SettlementReport {
	SettlementBlock proposedBlock;
	SettlementAcknowledgement acknowledgement;
	StateRootAccumulatorMessage stateRootMessage;
	uint256 settlementId;
	bytes32[] stateRoots;
}

struct StateRootAccumulatorMessage {
	// accumulator of all trades included in the block
	bytes32 tradeRoot;
	// accumulator of all outputs created by trades in this block
	bytes32 outputsRoot;
	// accumulator of all outputs spent by trades in this block
	bytes32 spentOutputsRoot;
	// accumulator of all outputs settled in this block
	bytes32 settledOutputsRoot;
	// id of trade which results in the above accumulators
	uint256 tradeIndex;
	// PI Signature of hash of above
	Signature piSig;
}

Trader Intents

A TraderIntent is a message signed by the Participating Interface. It represents an update to the ledger. The update must be valid (doesn't break constraints imposed by the ledger) and must reference a signed message from each trader involved.

All TraderIntent messages must be linearily sequenced by the Participating Interface.

Note that the Trade data type defined above is also considered a TraderIntent, as each trade must be the result of matching two trader-signed orders.

struct TraderIntent {
	uint256 id;
}

DepositAcknowledgement

A DepositAcknowledgement updates the ledger by creating a new output UTXO symmetric to the digital asset deposited by a trader in the AssetCustody smart contract.

struct DepositAcknowledgement {
	// Sequence ID
	uint256 tradeID;
	bytes32 depositUTXOHash;
	// Participating Interface ID
	address participatingInterface;
	// Participating Interface Signature
	uint8 v;
	bytes32 r;
	bytes32 s;
}

Settlement Acknowledgement

When a trader requests settlement of an asset, the PI must detect the smart contract event and take any action necessary to ensure that no further trades will occur that could affect that trader's balance of the asset. For example, a PI operating a limit order book should ensure that there are no active orders for products which include the requested asset.

Once a PI has confirmed that the trader's balance is now static, it signs and emits a message that's included in the same sequence as trades.

struct SettlementAcknowledgement {
	SettlementRequest settlementRequest;
	// Input UTXOs
	bytes32[] inputUTXOs;
}

Last updated