@@ -102,15 +102,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery {
102
102
// exactIn: decrease received amountIn, rounding down
103
103
if (exactIn) amount = amount * feeMultiplier / 1e18 ;
104
104
105
- bool asset0IsInput;
106
- {
107
- address asset0 = eulerSwap.asset0 ();
108
- address asset1 = eulerSwap.asset1 ();
109
-
110
- if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true ;
111
- else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false ;
112
- else revert UnsupportedPair ();
113
- }
105
+ bool asset0IsInput = checkTokens (eulerSwap, tokenIn, tokenOut);
114
106
115
107
uint256 quote = binarySearch (eulerSwap, reserve0, reserve1, amount, exactIn, asset0IsInput);
116
108
@@ -242,4 +234,71 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery {
242
234
// Compute and return x = fInverse(y) using the quadratic formula
243
235
return Math.mulDiv (uint256 (int256 (sqrt) - B), 1e18 , A, Math.Rounding.Ceil);
244
236
}
237
+
238
+ /// @dev Max amount the pool can buy of tokenIn and sell of tokenOut
239
+ function getLimits (address eulerSwap , address tokenIn , address tokenOut )
240
+ external
241
+ view
242
+ returns (uint256 inLimit , uint256 outLimit )
243
+ {
244
+ IEulerSwap es = IEulerSwap (eulerSwap);
245
+ if (! IEVC (es.EVC ()).isAccountOperatorAuthorized (es.eulerAccount (), eulerSwap)) return (0 , 0 );
246
+
247
+ inLimit = outLimit = type (uint112 ).max;
248
+ bool asset0IsInput = checkTokens (es, tokenIn, tokenOut);
249
+
250
+ // Supply caps on input
251
+ {
252
+ IEVault vault = IEVault (asset0IsInput ? es.vault0 () : es.vault1 ());
253
+ uint256 maxDeposit = vault.debtOf (es.eulerAccount ()) + vault.maxDeposit (es.eulerAccount ());
254
+ if (maxDeposit < inLimit) inLimit = maxDeposit;
255
+ }
256
+
257
+ // Remaining reserves of output
258
+
259
+ {
260
+ (uint112 reserve0 , uint112 reserve1 ,) = es.getReserves ();
261
+ uint112 reserveLimit = asset0IsInput ? reserve1 : reserve0;
262
+ if (reserveLimit < outLimit) outLimit = reserveLimit;
263
+ }
264
+
265
+ // Remaining cash and borrow caps in output
266
+
267
+ {
268
+ IEVault vault = IEVault (asset0IsInput ? es.vault1 () : es.vault0 ());
269
+
270
+ uint256 cash = vault.cash ();
271
+ if (cash < outLimit) outLimit = cash;
272
+
273
+ (, uint16 borrowCap ) = vault.caps ();
274
+ uint256 maxWithdraw = decodeCap (uint256 (borrowCap));
275
+ maxWithdraw = vault.totalBorrows () > maxWithdraw ? 0 : maxWithdraw - vault.totalBorrows ();
276
+ if (maxWithdraw > cash) maxWithdraw = cash;
277
+ maxWithdraw += vault.convertToAssets (vault.balanceOf (es.eulerAccount ()));
278
+ if (maxWithdraw < outLimit) outLimit = maxWithdraw;
279
+ }
280
+ }
281
+
282
+ function decodeCap (uint256 amountCap ) internal pure returns (uint256 ) {
283
+ if (amountCap == 0 ) return type (uint256 ).max;
284
+
285
+ unchecked {
286
+ // Cannot overflow because this is less than 2**256:
287
+ // 10**(2**6 - 1) * (2**10 - 1) = 1.023e+66
288
+ return 10 ** (amountCap & 63 ) * (amountCap >> 6 ) / 100 ;
289
+ }
290
+ }
291
+
292
+ function checkTokens (IEulerSwap eulerSwap , address tokenIn , address tokenOut )
293
+ internal
294
+ view
295
+ returns (bool asset0IsInput )
296
+ {
297
+ address asset0 = eulerSwap.asset0 ();
298
+ address asset1 = eulerSwap.asset1 ();
299
+
300
+ if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true ;
301
+ else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false ;
302
+ else revert UnsupportedPair ();
303
+ }
245
304
}
0 commit comments