@@ -3,20 +3,40 @@ pragma solidity ^0.8.27;
3
3
4
4
import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol " ;
5
5
import {IEVault} from "evk/EVault/IEVault.sol " ;
6
- import {IEulerSwap} from "./interfaces/IEulerSwap.sol " ;
7
6
import {IEulerSwapPeriphery} from "./interfaces/IEulerSwapPeriphery.sol " ;
7
+ import {IERC20 , IEulerSwap, SafeERC20} from "./EulerSwap.sol " ;
8
8
9
9
contract EulerSwapPeriphery is IEulerSwapPeriphery {
10
- address private immutable evc;
11
-
12
- constructor (address evc_ ) {
13
- evc = evc_;
14
- }
10
+ using SafeERC20 for IERC20 ;
15
11
16
12
error UnsupportedPair ();
17
13
error OperatorNotInstalled ();
18
14
error InsufficientReserves ();
19
15
error InsufficientCash ();
16
+ error AmountOutLessThanMin ();
17
+ error AmountInMoreThanMax ();
18
+
19
+ /// @inheritdoc IEulerSwapPeriphery
20
+ function swapExactIn (address eulerSwap , address tokenIn , address tokenOut , uint256 amountIn , uint256 amountOutMin )
21
+ external
22
+ {
23
+ uint256 amountOut = computeQuote (IEulerSwap (eulerSwap), tokenIn, tokenOut, amountIn, true );
24
+
25
+ require (amountOut >= amountOutMin, AmountOutLessThanMin ());
26
+
27
+ swap (eulerSwap, tokenIn, tokenOut, amountIn, amountOut);
28
+ }
29
+
30
+ /// @inheritdoc IEulerSwapPeriphery
31
+ function swapExactOut (address eulerSwap , address tokenIn , address tokenOut , uint256 amountOut , uint256 amountInMax )
32
+ external
33
+ {
34
+ uint256 amountIn = computeQuote (IEulerSwap (eulerSwap), tokenIn, tokenOut, amountOut, false );
35
+
36
+ require (amountIn <= amountInMax, AmountInMoreThanMax ());
37
+
38
+ swap (eulerSwap, tokenIn, tokenOut, amountIn, amountOut);
39
+ }
20
40
21
41
/// @inheritdoc IEulerSwapPeriphery
22
42
function quoteExactInput (address eulerSwap , address tokenIn , address tokenOut , uint256 amountIn )
@@ -36,15 +56,41 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery {
36
56
return computeQuote (IEulerSwap (eulerSwap), tokenIn, tokenOut, amountOut, false );
37
57
}
38
58
39
- /// @dev High-level quoting function. It handles fees and performs
40
- /// state validation, for example that there is sufficient cash available.
59
+ /// @dev Internal function to execute a token swap through EulerSwap
60
+ /// @param eulerSwap The EulerSwap contract address to execute the swap through
61
+ /// @param tokenIn The address of the input token being swapped
62
+ /// @param tokenOut The address of the output token being received
63
+ /// @param amountIn The amount of input tokens to swap
64
+ /// @param amountOut The amount of output tokens to receive
65
+ function swap (address eulerSwap , address tokenIn , address tokenOut , uint256 amountIn , uint256 amountOut ) internal {
66
+ IERC20 (tokenIn).safeTransferFrom (msg .sender , eulerSwap, amountIn);
67
+
68
+ bool isAsset0In = tokenIn < tokenOut;
69
+ (isAsset0In)
70
+ ? IEulerSwap (eulerSwap).swap (0 , amountOut, msg .sender , "" )
71
+ : IEulerSwap (eulerSwap).swap (amountOut, 0 , msg .sender , "" );
72
+ }
73
+
74
+ /// @dev Computes the quote for a swap by applying fees and validating state conditions
75
+ /// @param eulerSwap The EulerSwap contract to quote from
76
+ /// @param tokenIn The input token address
77
+ /// @param tokenOut The output token address
78
+ /// @param amount The amount to quote (input amount if exactIn=true, output amount if exactIn=false)
79
+ /// @param exactIn True if quoting for exact input amount, false if quoting for exact output amount
80
+ /// @return The quoted amount (output amount if exactIn=true, input amount if exactIn=false)
81
+ /// @dev Validates:
82
+ /// - EulerSwap operator is installed
83
+ /// - Token pair is supported
84
+ /// - Sufficient reserves exist
85
+ /// - Sufficient cash is available
41
86
function computeQuote (IEulerSwap eulerSwap , address tokenIn , address tokenOut , uint256 amount , bool exactIn )
42
87
internal
43
88
view
44
89
returns (uint256 )
45
90
{
46
91
require (
47
- IEVC (evc).isAccountOperatorAuthorized (eulerSwap.myAccount (), address (eulerSwap)), OperatorNotInstalled ()
92
+ IEVC (eulerSwap.EVC ()).isAccountOperatorAuthorized (eulerSwap.myAccount (), address (eulerSwap)),
93
+ OperatorNotInstalled ()
48
94
);
49
95
50
96
uint256 feeMultiplier = eulerSwap.feeMultiplier ();
@@ -83,9 +129,17 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery {
83
129
return quote;
84
130
}
85
131
132
+ /// @notice Binary searches for the output amount along a swap curve given input parameters
86
133
/// @dev General-purpose routine for binary searching swapping curves.
87
134
/// Although some curves may have more efficient closed-form solutions,
88
135
/// this works with any monotonic curve.
136
+ /// @param eulerSwap The EulerSwap contract to search the curve for
137
+ /// @param reserve0 Current reserve of asset0 in the pool
138
+ /// @param reserve1 Current reserve of asset1 in the pool
139
+ /// @param amount The input or output amount depending on exactIn
140
+ /// @param exactIn True if amount is input amount, false if amount is output amount
141
+ /// @param asset0IsInput True if asset0 is being input, false if asset1 is being input
142
+ /// @return output The calculated output amount from the binary search
89
143
function binarySearch (
90
144
IEulerSwap eulerSwap ,
91
145
uint112 reserve0 ,
0 commit comments