DeDust Hub
Quickstart

Swap

Swapping is the primary operation of a DEX, allowing users to exchange one asset for another. In DeDust Protocol V2, swaps are executed against a Pool contract using the Constant Product formula (x×y=kx \times y = k).

Depending on the input asset (Native TON or Jetton), the interaction flow differs slightly, but the core swap logic defined in tgithe SwapPayload remains the same.

Swap Payload

Swaps are implemented using the payment abstraction. This means that the instructions for the swap are provided as a Payment Payload, which is attached to the asset transfer.

SwapPayload is the specific payment payload structure used to request a swap. It encapsulates all the necessary parameters for the trade, independent of whether you are paying with TON or Jettons.

struct (0xc442500f) SwapPayload {
    minimalAmountOut: coins
    deadline: uint40
    next: Cell<SwapStep>?
    partnerConfig: PartnerConfig?
    referrerConfig: ReferrerConfig?
}

Parameters

FieldDescription
minimalAmountOutSlippage Protection. The minimum amount of the output asset you are willing to accept. If the pool cannot provide at least this amount (due to price changes or low liquidity), the transaction will be aborted and assets refunded.
deadlineTime Limit. A Unix timestamp. If the transaction is processed by the blockchain after this time, it will be rejected. This protects against miner withholding attacks where a transaction is held until market conditions are unfavorable.
nextMulti-hop Routing. An optional reference to a SwapStep. If provided, the output of the current swap is automatically forwarded to another pool defined in SwapStep to perform the next trade.
partnerConfigOptional configuration for partner fees.
referrerConfigOptional configuration for referrer fees.

Swapping TON (Native -> Jetton)

To swap TON for a Jetton, you must send a PayNative message directly to the Pool contract.

Implementation

When constructing the PayNative message:

  • Amount: The amount of TON you want to swap.
  • Payment Payload: The SwapPayload cell.
  • Payout Config: Defines where to send the output Jettons and where to send refunds if the swap fails.

Flow Diagram

The following diagram illustrates the flow of a swap from TON to a Jetton:

PayNative (TON + SwapPayload) Emit SwapEvent Transfer (Jetton amount) Jetton Transfer Excesses (Remaining Gas) 1. Validate swap parameters 2. Calculate amount out & fees 3. Update reserves User Pool Pool's Jetton Wallet

Swapping Jettons (Jetton → TON / Jetton)

To swap a Jetton (for TON or another Jetton), you perform a standard Jetton Transfer to the Pool's address. The swap parameters are passed inside the forward_payload of the transfer.

The forward_amount in the transfer must be sufficient to cover the gas costs of the swap execution and any subsequent transfers.

Payload Structure

The forward_payload of the jetton transfer MUST contain a PayJetton structure.

struct (0xcbc33949) PayJetton {
    paymentPayload: Cell<SwapPayload>
    payoutConfig: Cell<ExtendedPayoutConfig>
}

Jetton to TON Flow

Transfer (Amount + PayJetton) Internal Transfer Transfer Notification Emit SwapEvent Payout (TON amount) Excesses (Remaining Gas) 1. Parse PayJetton 2. Execute Swap to TON User User's Jetton Wallet Pool's Jetton Wallet Pool

Jetton to Jetton Flow

Swapping one Jetton (Asset X) for another Jetton (Asset Y) follows the same initial process. The Pool detects the output asset is a Jetton and sends a transfer instruction to its own wallet for Asset Y.

Transfer (Amount + PayJetton) Internal Transfer Transfer Notification Emit SwapEvent Transfer (Jetton Y amount) Internal Transfer Transfer Notification 1. Execute Swap X -> Y User User's Jetton Wallet X Pool's Jetton Wallet X Pool Pool's Jetton Wallet Y User's Jetton Wallet Y

Multi-hop Swaps

DeDust Protocol V2 supports atomic multi-hop swaps (e.g., Token A → TON → Token B) in a single transaction chain. This is achieved using the next field in the SwapPayload.

Instead of sending the output assets to the user, the pool wraps them into a new payment message and forwards them to the next pool address defined in SwapStep.

SwapStep Structure

struct SwapStep {
    pool: address
    minimalAmountOut: coins
    deadline: uint40
    next: Cell<SwapStep>?
}

Example Flow (A → TON → B)

  1. User initiates swap of Token A at Pool 1 (A/TON).
  2. The SwapPayload provided to Pool 1 has a next field containing a SwapStep.
  3. The SwapStep points to Pool 2 (TON/B).
  4. Pool 1 executes A → TON.
  5. Instead of paying TON to the user, Pool 1 sends a PayNative message to Pool 2 with the resulting TON and the next payload.
  6. Pool 2 receives the TON, executes TON → B, and sends Token B to the user.
Swap A -> TON (with next step) Emit SwapEvent PayNative (100 TON + SwapStep) Emit SwapEvent Transfer Token B Output: 100 TON Swap TON -> B User Pool A/TON Pool TON/B

On this page