# vExchangeReserves

## Events

### Event ReservesExchanged

```solidity
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

```solidity
event NewIncentivesLimit(uint256 newLimit);
```

Emitted when incentives limit percentage is changed in changeIncentivesLimitPct

## State-Changing Functions

### function exchange

```solidity
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 ](https://docs.virtuswap.io/virtuswap-documentation/virtuswap-basics/virtuswap-technology/exchange-of-reserves)for background.

The two exchanging pools are specified by `jkPair1` (*Source Pool*) and `jkPair2` (*Target Pool*).&#x20;

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.&#x20;

`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`](https://docs.virtuswap.io/virtuswap-documentation/technical-reference/smart-contracts-v1/vpair#function-swapnativetoreserve) method is called on the *Source Pool.* That method sends reserve tokens to the target pool and initiates a callback [`vExchangeReserves.vFlashSwapCallback`](#function-vflashswapcallback) method, which in turn calls [`swapNativeToReseve`](https://docs.virtuswap.io/virtuswap-documentation/technical-reference/smart-contracts-v1/vpair#function-swapnativetoreserve) 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.&#x20;

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.&#x20;

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

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)&#x20;

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`](#function-changeincentiveslimitpct) method.

Parameters:

<table><thead><tr><th width="195">Name</th><th width="161">Type</th><th>Description</th></tr></thead><tbody><tr><td>jkPair1</td><td><code>address</code></td><td>The source pool of the reserve exchange</td></tr><tr><td>ikPair1</td><td><code>address</code></td><td>The reference pool combined with the source pool to create a virtual pool to define the ratio of reserve prices </td></tr><tr><td>jkPair2</td><td><code>address</code></td><td>The target pool of the reserve exchange</td></tr><tr><td>ikPair2</td><td><code>address</code></td><td>The reference pool combined with the target pool to create a virtual pool to define the ratio of reserve prices </td></tr><tr><td>flashAmountOut</td><td><code>uint256</code></td><td>Amount of reserve asset in the source pool to be exchanged</td></tr></tbody></table>

#### function vFlashSwapCallback

```solidity
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`](https://docs.virtuswap.io/virtuswap-documentation/technical-reference/smart-contracts-v1/vpair#function-swapnativetoreserve) method on the *Target Pool*.

Parameters:

<table><thead><tr><th width="216">Name</th><th width="181">Type</th><th>Description</th></tr></thead><tbody><tr><td>tokenIn</td><td><code>address</code></td><td>Token to be sent</td></tr><tr><td>tokenOut</td><td><code>address</code></td><td>Token to be received</td></tr><tr><td>requiredBackAmount</td><td><code>uint256</code></td><td>Amount to be sent</td></tr><tr><td>data</td><td><code>bytes calldata</code></td><td><p><a href="#function-vflashswapcallback-1"><code>ExchangeReserveCallbackParams</code></a> structure that is passed to swapNativeToReserve method of the jkPair1 pool, and subsequently to vFlashSwapCallback method of vExchange Reserves"</p><pre><code>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
</code></pre></td></tr></tbody></table>

#### function changeIncentivesLimitPct

```solidity
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

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

Defines the callback parameters to be passed to the [`exchange`](#function-exchange) function and subsequently to the [`vFlashSwapCallback`](#function-vflashswapcallback) of [`vExchangeReserves`](https://docs.virtuswap.io/virtuswap-documentation/technical-reference/smart-contracts-v1/dex-contracts/vexchangereserves) contract.&#x20;
