The multi-asset trade flow

Traders can trade multiple types of assets among multiple parties.

Some use cases:

  • Trade a combination of different NFTs in a single transaction.

  • Pay fees to multiple parties in a single transaction.

  • More than two parties can participate in a trade. For example, Alice gives Bob one ETH, Bob gives Carol 1000 USDC, and Carol gives Alice one dragon and two castle NFTs.

A multi-asset trade consists of multiple orders and their fulfillment information. Each order can come from a different party. All orders must be completely fulfilled. Partial fulfillment is not supported.

When a user submits an order, you, the operator, need to find orders from other users that match. When you match multi-asset trade orders, you need to consider the fee that you want to receive for order fulfillment, and calculate that fee as part of the match.

StarkEx enables a user to specify multiple recipients for a single asset. For example, Alice can send two USDC to Bob and one USDC to Carol. Or Alice can specify that each of the four swords she receives should be deposited to four separate vaults.

Fees

You can take fees from participants as part of the trade. For example, Alice sells one NFT for 10 ETH, and Bob purchases one NFT for 12 ETH. You can then create a MultiAssetTradeRequest transaction in which Alice receives 10 ETH, Bob receives one NFT, and you receive one ETH. Alternatively, you can create a MultiAssetTradeRequest transaction in which Alice receives 10 ETH to her own vault and 2 ETH to your vault and Bob receives one NFT. Either way, StarkEx is not aware of which values are fees.

Example of a multi-asset trade

In the following example, each side wants to give and receive certain assets, as shown in the following table:

Table 1. Matching orders in a multi-asset trade
Dragons Magic cards USDC ETH Swords Shields

Alice

Give 1

Give 2

Give 16

Receive 2

Receive 4

Receive 1

Bob

Receive 1

Give 1

Give 2

Carol

Receive 2

Receive 14

Give 4

Give 1

The operator

Receive 3
(Desired fee)

The three orders complement each other exactly, so the operator can fulfill all of them completely, and take the desired fee of three USDC. If the orders did not complement each other exactly, the application would not match them.

1. Alice, Bob, and Carol enter orders using the off-chain application.

Alice, Bob, and Carol enter multi-asset trade orders using the off-chain application, detailing the assets they each want to buy and sell. Depending on the business logic of your application, one or more of their orders should include the fee that you require to fulfill the transaction.

The application searches for one or more orders such that it can fulfill all orders completely.

2. The application sends a multi-asset trade request to StarkEx.

The application matches the limit orders of Alice, Bob, and Carol, and sends a multi-asset trade request transaction to the StarkEx gateway, using the add_transaction API with the MultiAssetTradeRequest transaction type. The API call includes all orders, including the actual amounts transferred between Alice’s, Bob’s, and Carol’s vaults.

The request that the application sends to the StarkEx gateway includes a list of orders, where each order includes the following information:

nonce

A unique nonce issued by the caller.

expiration_timestamp

The expiration timestamp of the order, in hours since the Unix epoch.

give

A list of amounts payable from each vault that gives assets in the order. These amounts are the maximum that the sender is willing to pay for each asset in the order. For each asset, the order includes the following information:

asset_id

The token’s identifier.

vault_id

The vault that holds the token to give.

amount

The amount of tokens to give.

receive

A list of amounts receivable for each vault that receives assets in the order. These amounts are the minimum that the receiver is willing to accept for each asset in the order. For each received asset, the order includes the following information:

public_key

The public address of the recipient vault’s owner.

asset_id

The token’s identifier.

vault_id

The vault that receives the token.

amount

The amount of tokens to receive into this vault.

public_key

The public Stark key of the order’s sender, as registered on the StarkEx contract.

signature

The signature of the order’s sender.

3. StarkEx validates the request.

StarkEx checks the following to validate the transaction request:

  • The ids of the assets of the orders in the list match.

  • Every giver in an order gives at most the value specified by give.

  • For each entry in give, the specified vault sends at most the specified amount.

  • For each entry in receive, the specified vault receives at least the specified amount.

  • Each of the orders in the transaction request is signed by a Stark key that corresponds to the list of vault ids specified in give.

  • The balance in each vault ID is sufficient to fulfill the trade.

  • Neither order has already been fulfilled, and the amount to be traded does not cause Alice or Bob to transfer more than what they signed on in the order.

  • The transaction request has not expired.

4. StarkEx includes the transaction in a batch.

If the transaction request is valid, the multi-asset trade is included in a batch to be submitted on-chain along with a validity proof.

Implementing a multi-asset trade in your application

To implement multi-asset trade functionality in your application, use the add_transaction API with the MultiAssetTradeRequest transaction type.

The StarkEx API does not include a parameter dedicated to charging fees. Instead, specify the fee information in the fulfillment_info parameter of MultiAssetTradeRequest.

The StarkEx REST API reference includes all necessary information.

Additional resources