You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/swaps.md
+14-11Lines changed: 14 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -45,14 +45,16 @@ Finally a `multicall` function allows chaining all of the above to execute compl
45
45
The swaps can be performed in one of 3 modes:
46
46
- exact input
47
47
48
-
In this mode, all of the provided input token is expected to be swapped for an unknown amount of the output token. The proceeds are expected to be sent to a vault, to be skimmed by the user, or back to the swapper contract. The latter option is useful when performing complex, multi-stage swaps, where the output token is accumulated in the swapper before being consumed at the end of the operation. Note that the available handlers (1Inch and Uniswap Auto Router) execute a payload encoded off-chain, so a lot of the parameters passed to the `swap` funtion will be ignored and only the amount of input token encoded in the payload will be swapped, even if the swapper holds more.
48
+
In this mode, all of the provided input token is expected to be swapped for an unknown amount of the output token. The proceeds are expected to be sent to a vault, to be skimmed by the user, or back to the swapper contract. The latter option is useful when performing complex, multi-stage swaps, where the output token is accumulated in the swapper before being consumed at the end of the operation. Note that the available handler (`GenericHandler`) executes a payload encoded off-chain, so a lot of the parameters passed to the `swap` funtion will be ignored and only the amount of input token encoded in the payload will be swapped, even if the swapper holds more.
49
49
50
50
- exact output
51
51
52
52
In this mode, the swapper is expected to purchase a specified amount of the output token in exchange for an unknown amount of the input token. The input token amount provided to the swapper acts as an implicit slippage limit. Currently available handlers (Uniswap V2 and V3) will check the current balance of the output token held by the swapper and adjust the amount of token to buy to only purchase the remainder. This feature can be used to construct multi-stage swaps. For instance, in the first stage, most of the token is bought through a dex aggregator, which presumably offers better price, but doesn't provide exact output swaps. The proceeds are directed to the swapper contract. In the second stage another `swap` call is executed, and the remainder is bought directly in Uniswap, where exact output trades are supported.
53
53
54
54
In exact output trades, the remaining, unused input token amount is automatically redeposited for the account specified in `SwapParams.accountIn` in a vault specified in `SwapParams.vaultIn`.
55
55
56
+
Note that the generic handler can also be invoked in exact output mode. The swap will be executed as per the request encoded off-chain, but swapper will attempt to return unused input token balance if any.
57
+
56
58
- target debt (swap and repay)
57
59
58
60
In this mode, the swapper will check how much debt a provided account has (including current interest accrued), compare it with a target debt the user requests, and the amount already held by the swapper contract, and by exact output trade will buy exactly the amount required to repay the debt (down to the target amount). In most cases the target amount will be zero, which means the mode can be used to close debt positions without leaving any dust.
@@ -63,18 +65,20 @@ The swaps can be performed in one of 3 modes:
63
65
64
66
Finally, and similarly to exact output, any unused input will be redeposited for the `accountIn`.
65
67
68
+
Note that the generic handler can also be invoked in target debt mode. In such a case there will be no on-chain modification to the swap payload, but swapper will attempt a repay and return of the unused input as per swap params.
69
+
66
70
67
71
### Handlers
68
72
69
73
The swapper contract executes trades using external providers like 1Inch or Uniswap. Internal handler modules take care of interfacing with the provider. They are enumerated by a `bytes32` encoded string. The available handlers are listed as constants in `Swapper.sol`.
70
74
71
-
-1Inch handler
75
+
-Generic handler
72
76
73
-
Only supports `exact input` mode. Executes a payload returned by [1Inch API](https://portal.1inch.dev/documentation/swap/introduction) on the aggregator contract.
77
+
Executes arbitrary call on arbitrary target address. Presumably they are calls to swap providers. For example a payload returned by [1Inch API](https://portal.1inch.dev/documentation/swap/introduction) on the aggregator contract or payloads created with [Uniswap's Auto Router](https://github.com/Uniswap/smart-order-router) on [SwapRouter02](https://etherscan.io/address/0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45)
74
78
75
-
- Uniswap Auto Router handler
79
+
Generic handler accepts all 3 swapping modes, although for most swap providers only exact input is natively available. Although the off-chain data will not be modified to match the actual on-chain conditions during execution, swapper will carry out post processing according to the swap mode: returning unused input token in exact output mode or repaying debt in target debt mode. See F5 in [Common flows](#common-flows-in-evk) for one possible use case.
76
80
77
-
Supports `exact input` and `exact output` modes. Executes payloads created with [Uniswap's Auto Router](https://github.com/Uniswap/smart-order-router) on [SwapRouter02](https://etherscan.io/address/0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45). Payload is simply executed in both modes, so in exact output, the handler will not try to update the amount bought with balance already present in the swapper, as the other uniswap handlers.
81
+
The data passed to the handler in `SwapParams.data` should be an abi encoded tuple: target contract address and call data
78
82
79
83
- Uniswap V2 handler
80
84
@@ -98,15 +102,15 @@ F1. Swap exact amount of deposits from one EVault (A) to another (B)
98
102
- fetch a swap payload from either 1Inch api or Uniswap Auto Router, setting B as the receiver
99
103
- create EVC batch call with the following items:
100
104
-`A.withdraw` the required input token amount to the swapper contract
101
-
-`Swapper.swap` - `exact input` on the selected handler
105
+
-`Swapper.swap` - `exact input` on the generic handler
102
106
-`SwapVerifier.verifyAmountMinAndSkim` Check a minimum required amount was bought for the input, according to slippage settings and claim it for the user.
103
107
104
108
F2. Swap deposits from one EVault (A) to exact amount of another (B)
105
109
- find an exact input payload on 1Inch or Uniswap Auto Router such that most of the required output amount is bought. E.g., binary search input amount that yields 98% of the required output amount. The receiver encoded in the payload must be the swapper contract.
106
110
- create EVC batch with the following items:
107
111
-`A.withdraw` to the swapper contract. The amount must cover all of the estimated swap costs with some extra, to account for slippage
108
112
-`swapper.multicall` with the following items:
109
-
-`Swapper.swap` - `exact input` with the off-chain payload
113
+
-`Swapper.swap` - `exact input`on the generic handler with the off-chain payload
110
114
-`Swapper.swap` - `exact output` on one of the supportin handlers (Uni V2/V3) with the user specified `amountOut`. The receiver can be either the swapper contract or B vault.
111
115
-`Swapper.sweep` the output token, into the B vault
112
116
-`SwapVerifier.verifyAmountMinAndSkim` check a minimum required amount was bought and claim the funds for the user. Because exact output swaps are not guaranteed to be exact always, a small slippage could be allowed.
@@ -127,9 +131,8 @@ F4. Sell deposits from one vault (A) to repay debt in another (B)
127
131
F5. Sell deposit from one vault (A) to repay debt in another (B) when exact output is unavailable
128
132
129
133
For some token pairs, the exact output swap might not be available at all, or the price impact might be too big due to poor liquidity in Uniswap. In such cases to repay the full debt:
130
-
- find an exact input payload on 1Inch or Uniswap Auto Router, to buy slightly **more** of the output token than is necessary to repay the debt, taking into account slippage on exchanges and interest accrual between the payload generation and transaction execution. E.g., binary search input amount that yields 102% of the current debt. Set the receiver to the liability vault.
134
+
- find an exact input payload on 1Inch or Uniswap Auto Router, to buy slightly **more** of the output token than is necessary to repay the debt, taking into account slippage on exchanges and interest accrual between the payload generation and transaction execution. E.g., binary search input amount that yields 102% of the current debt (2% slippage limit). Set the receiver to the liability vault.
131
135
- create EVC batch with the following items:
132
136
-`A.withdraw` the required input token amount to the swapper contract
133
-
-`Swapper.swap` - `exact input` on the selected handler
134
-
-`SwapVerifier.verifyAmountMinAndSkim` check that the minimum required amount was bought and claim it for the user
135
-
-`B.repayWithShares` setting the amount to max uint256. Debt should be removed to zero, with the remainder of the output token deposited in B vault for the borrower.
137
+
-`Swapper.swap` - `target debt` on the generic handler. The `amountOut` should be set to the amount of debt the user requested to have after the operation. Set to zero, to repay full debt.
138
+
-`SwapVerifier.verifyDebtMax` check that the user's debt matches the expectations
0 commit comments