SIP-268: Curve Integration

ProposalLoading status...

Simple Summary

This sip builds on top of SIP-267's direct integration functionality in order to offer an end-to-end cross-asset swap function at reduced fees, built on top of Synthetix's atomic exchanges and Curve's stable swap pools.


The CurveIntegration sip allows users to trade between non-synths at reduced fees, with the trade executing by hoping over curve stable-swap pools along side Synthetix's atomic swap function. A user would be able to spend synthEquivalent and receive another synthEquivalent with the swap taking place with the following route:

  • synthEquivalent to synth over curve's stable swaps (USDC to sUSD)
  • synth to synth with atomic swaps (sUSD to sETH)
  • synth to synthEquivalent over curve's stable swaps (sETH to wETH)

As an implementation note, no partial trades are allowed and the full route from synthEquivalent to synthEquivalent needs to be executed atomically within the same transaction.


The CurveIntegration contract takes advantage of the slippage model incorporated within curve's stable-swap pools, helping stall toxic volume to the extent of the imbalance in individual curve pools. This allows the protocol to lower Synthetix's exchange fees with the help of SIP-267's override function and designate the 30 bp uniswap pool as a source of pricing. Therefore, swaps that do not take place within the CurveIntegration contract would continue to trade using the pricing of the 5 bp uniswap pool, at their own independently configured fees.


Technical Specification

Synth Equivalent Specification

  • All the synth tokens that can be traded within the CurveIntegration contract need be assigned respective synthEquivalents via setSynthEquivalent function. The designated synthEquivalent tokens need to exist in the Curve Stable-Swap pools specified in the next section.

For example sUSD would be assigned USDC as synthEquivalent and sETH would have wETH as synthEquivalent.

  • ETH cannot be designated as a synthEquivalent, hence a wETH/sETH curve stable swap pool would need to be created.

Curve Stable Pool Specification

  • Each synthEquivalent & synth pair need to be mapped to a specific curve pool containing the respective these tokens. The specification would be done by calling setCurvePoolForSynthExchange function which takes in the address of the curve contract as an argument as well as the currencyKey of the synth.
  • No curve meta-pools can be configured, as the curve pool needs to contain both the synthEquivalent and synth tokens.

Direct Integration Contract Designation

The CurveIntegration contract needs to be pointed to the DirectIntegration contract, in order to be able to trade atomically with Synthetix's atomic function and retrieve the respective fee and pricing parameters, taking into account overrides.

Swap Pricing Methodology

  1. Naming Convention:

    • sourceEquivalent is the token spent by the user
    • sourceSynth is the synth obtained by trading the sourceEquivalent token on the specified curve stable swap pool
    • destinationSynth is the synth obtained by trading the sourceSynth over Synthetix's atomic exchange
    • destinationEquivalent is token received by the user when trading destinationSynth on the specified stable swap curve pool
    • Crv(sourceEquivalent,sourceSynth) is the rate of exchange obtained from curve, swapping a sourceSynth per unit of sourceEquivalent
    • Atomic(sourceSynth,destinationSynth) is Synthetix's atomic rate of exchange of a destinationSynth token per unit of sourceSynth
    • Crv(destinationSynth,destinationEquivalent) is the rate of exchange obtained from curve, swapping a destinationEquivalent token per unit of destinationSynth
  2. Curve Integration Pricing Function:

    The CurveIntegration price is obtained using the function below:

    Crv(sourceEquivalent,sourceSynth) * Atomic(sourceSynth,destinationSynth) * Crv(destinationSynth,destinationEquivalent)

    Note that both the Curve and Synthetix fill price are dependent on the amount of exchange at each step.

A getReturnAmount function would be incorporated into the CurveIntegration which takes in the following arguments:

  • The address of the sourceEquivalent token
  • The address destinationEquivalent token
  • The sourceAmount representing the amount spent by the user

The function returns the amount expected to be received in destinationEquivalent token, by trading over the CurveIntegration contract.

In case a synth is tagged to trade at the pure chainlink price, then the chainlink price used to fetch the price over atomic pricing. It is worth nothing that with the current implementation of the atomic swaps functionality, the protocol does not need to map synths that trade at the pure chainlink price to synthEquivalents, since no uniswap pool is used. However, in order for the CurveIntegration contract to be able to handle swaps with synths that trade at pure chainlink price, a synthEquivalent needs to be designated.

Min Return

A minReturn function will be incorporated into CurveIntegration swap function, representing the minimum return amount a user accepts to receive in synthEquivalent for the amount of synthEquivalent spent. In case the return amount is below the minReturn, the transaction reverts.

Test Cases

Configurable Values (Via SCCP)

  • setCurvePoolForSynthExchange allows the Spartan Council to designate the Curve Stable-Swap contract over which the synthEquivalent to synth trade executes.
  • setSynthEquivalent allows the Spartan Council to designate the respective equivalent for each synth that can be traded on Crv pools.

SIP rejected by author as the SIP-267 implementation does not require that SIP-268 be implemented as any address can be configured for integration.

Copyright and related rights waived via CC0.