vExchangeReserves

Performs exchange of reserves of between vPair instances

Events

Event ReservesExchanged

event ReservesExchanged(
    address jkPair1,
    address ikPair1,
    address jkPair2,
    address ikPair2,
    uint256 requiredBackAmount,
    uint256 flashAmountOut,
    address leftOverToken,
    uint leftOverAmount
);

emitted after exchange reserves trade is completed.

Event NewIncentivesLimit

event NewIncentivesLimit(uint256 newLimit);

Emitted when incentives limit percentage is changed in changeIncentivesLimitPct

State-Changing Functions

function exchange

function exchange(
    address jkPair1,
    address ikPair1,
    address jkPair2,
    address ikPair2,
    uint256 flashAmountOut
) external

The method initiates reserve exchange between two vPair instances. See Exchange of Reserves for background.

The two exchanging pools are specified by jkPair1 (Source Pool) and jkPair2 (Target Pool).

The flashAmountOut of the reserve asset in the Source Pool (Source Asset) is exchanged for a corresponding amount of a specific reserve asset in the Target Pool (target asset). The source asset must be a native asset of the target pool, and the target asset must be a native asset in the source pool.

For each pool, a corresponding reference pool is defined (ikPair1 and ikPair2 respectively). The reference pools are used to create virtual pools that define relative prices of the two assets.

ikPair1 and ikPair2 implicitly define the two assets that are being exchanged. Specifically, Source Asset is the native asset of ikPair1 that is not native to jkPair1, and Target Asset is the native asset of ikPair2 that is not native to jkPair2.

The exchange is performed as flash exchange. Initially, the swapNativeToReserve method is called on the Source Pool. That method sends reserve tokens to the target pool and initiates a callback vExchangeReserves.vFlashSwapCallback method, which in turn calls swapNativeToReseve on the Target Pool. The Target Pool, in turn, sends the requested amount and validates that the amount received is greater or equal to the value of the source asset sent. The control returns back to the Source Pool, that validates that the received amount is greater or equal to the value of the target asset sent and completes the transaction

Example:

Let's assume we have a pool A/B holding C in reserve: A/B [C]

We also have another pool C/D holding A: C/D [A]

In order to perform the reserve exchange procedure between the two pools, we want to exchange C in pool A/B with A in pool C/D.

In this case, jkPair1 is A/B, jkPair2 in C/D. We also need two virtual pools connecting A and C, one built from jkPair1 and the other built from jkPair2, in order to determine the price of A in terms of C and vice a versa.

The pool ikPair1 should be B/C, so that a virtual pool A/C can be built from jkPair1 and ikPair1, and the pool ikPair2 should be D/A, so that a virtual pool A/C can be built from jkPair2 and ikPair2

Caller Incentives

Exchange is a public function that incentivizes its caller to search for opportunities to exchange pools reserves and pay the gas fees required to perform the exchanges.

The incentive comes from the difference in prices between the two virtual pools involved in the proposed exchange.

Continuing the example above, consider two virtual pools provided by the caller to determine the relative prices of A and C:

- C/A (which consists of jkPair A/B and ikPair B/C)

-A/C (which consists of jkPair C/D and ikPair D/A)

In most cases, the prices will not be exactly equal due to the different native pools they consist of. For example, the A/C price in the first virtual pool may be 0.1 and the price in the second pool may be 0.09938.

A certain percentage of the leftovers, specified by the incentivesLimitPct variable is sent to the caller as a reward for running the transaction. Initially, the Reserve Exchange routine will be called by the VirtuSwap DAO, and incentivesLimitPct will be set to 0, i.e. all the leftovers will remain in the pools. The incentives percentage can be changed using changeIncentivesLimitPct method.

Parameters:

Name
Type
Description

jkPair1

address

The source pool of the reserve exchange

ikPair1

address

The reference pool combined with the source pool to create a virtual pool to define the ratio of reserve prices

jkPair2

address

The target pool of the reserve exchange

ikPair2

address

The reference pool combined with the target pool to create a virtual pool to define the ratio of reserve prices

flashAmountOut

uint256

Amount of reserve asset in the source pool to be exchanged

function vFlashSwapCallback

function vFlashSwapCallback(
    address tokenIn,
    address tokenOut,
    uint256 requiredBackAmount,
    bytes calldata data
) external override

Called by the Source Pool during the reserve exchange. The method calls swapNativetoReserve method on the Target Pool.

Parameters:

Name
Type
Description

tokenIn

address

Token to be sent

tokenOut

address

Token to be received

requiredBackAmount

uint256

Amount to be sent

data

bytes calldata

ExchangeReserveCallbackParams structure that is passed to swapNativeToReserve method of the jkPair1 pool, and subsequently to vFlashSwapCallback method of vExchange Reserves"

jkPair1: source pool, same as jkPair1 
         pool above
jkPair2: target pool, same as jkPair2 
         pool above
ikPair2: Reference pool used by to 
         create a virtual pool with
         jkPair2

function changeIncentivesLimitPct

function changeIncentivesLimitPct(uint256 newLimit) external;

Sets the percentage of leftovers resulting from a reserve exchange that should be sent back to the caller.

Data Structures

struct ExchangeReserveCallbackParams

struct ExchangeReserveCallbackParams {
    address jkPair1;
    address jkPair2;
    address ikPair2;
}

Defines the callback parameters to be passed to the exchange function and subsequently to the vFlashSwapCallback of vExchangeReserves contract.

Last updated