Skip to content

Commit 46f4f2c

Browse files
authored
Merge pull request #6 from euler-xyz/chore
Chore: add interfaces & minor updates
2 parents 3923837 + 7f2e434 commit 46f4f2c

File tree

6 files changed

+127
-3
lines changed

6 files changed

+127
-3
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ out/
99

1010
# Dotenv file
1111
.env
12+
13+
# Coverage file
14+
lcov.info

src/MaglevBase.sol

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import {EVCUtil} from "evc/utils/EVCUtil.sol";
55
import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol";
66
import {IEVault, IERC20, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol";
77
import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol";
8+
import {IMaglevBase} from "./interfaces/IMaglevBase.sol";
89

9-
abstract contract MaglevBase is EVCUtil {
10+
abstract contract MaglevBase is IMaglevBase, EVCUtil {
1011
address public immutable vault0;
1112
address public immutable vault1;
1213
address public immutable asset0;
@@ -51,6 +52,9 @@ abstract contract MaglevBase is EVCUtil {
5152
vault1 = params.vault1;
5253
asset0 = IEVault(vault0).asset();
5354
asset1 = IEVault(vault1).asset();
55+
56+
require(asset0 != asset1, UnsupportedPair());
57+
5458
myAccount = params.myAccount;
5559
reserve0 = offsetReserve(params.debtLimit0, vault0);
5660
reserve1 = offsetReserve(params.debtLimit1, vault1);
@@ -82,7 +86,7 @@ abstract contract MaglevBase is EVCUtil {
8286

8387
// Invoke callback
8488

85-
if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data);
89+
if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(_msgSender(), amount0Out, amount1Out, data);
8690

8791
// Deposit all available funds, adjust received amounts downward to collect fees
8892

src/MaglevEulerSwap.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ pragma solidity ^0.8.27;
33

44
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
55
import {MaglevBase} from "./MaglevBase.sol";
6+
import {IMaglevEulerSwap} from "./interfaces/IMaglevEulerSwap.sol";
67

7-
contract MaglevEulerSwap is MaglevBase {
8+
contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase {
89
uint256 public immutable priceX;
910
uint256 public immutable priceY;
1011
uint256 public immutable concentrationX;

src/interfaces/IMaglevBase.sol

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity >=0.8.0;
3+
4+
interface IMaglevBase {
5+
function configure() external;
6+
function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;
7+
function quoteExactInput(address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256);
8+
function quoteExactOutput(address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256);
9+
10+
function vault0() external view returns (address);
11+
function vault1() external view returns (address);
12+
function asset0() external view returns (address);
13+
function asset1() external view returns (address);
14+
function myAccount() external view returns (address);
15+
function debtLimit0() external view returns (uint112);
16+
function debtLimit1() external view returns (uint112);
17+
function feeMultiplier() external view returns (uint256);
18+
function reserve0() external view returns (uint112);
19+
function reserve1() external view returns (uint112);
20+
}

src/interfaces/IMaglevEulerSwap.sol

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity >=0.8.0;
3+
4+
import {IMaglevBase} from "./IMaglevBase.sol";
5+
6+
interface IMaglevEulerSwap is IMaglevBase {
7+
function priceX() external view returns (uint256);
8+
function priceY() external view returns (uint256);
9+
function concentrationX() external view returns (uint256);
10+
function concentrationY() external view returns (uint256);
11+
function initialReserve0() external view returns (uint112);
12+
function initialReserve1() external view returns (uint112);
13+
}

test/UniswapV2Call.t.sol

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
pragma solidity ^0.8.24;
3+
4+
import {IUniswapV2Callee} from "../src/interfaces/IUniswapV2Callee.sol";
5+
// import {Test, console} from "forge-std/Test.sol";
6+
import {MaglevTestBase} from "./MaglevTestBase.t.sol";
7+
import {MaglevEulerSwap as Maglev} from "../src/MaglevEulerSwap.sol";
8+
9+
contract UniswapV2CallTest is MaglevTestBase {
10+
Maglev public maglev;
11+
SwapCallbackTest swapCallback;
12+
13+
function setUp() public virtual override {
14+
super.setUp();
15+
16+
createMaglev(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18);
17+
18+
swapCallback = new SwapCallbackTest();
19+
}
20+
21+
function createMaglev(
22+
uint112 debtLimit0,
23+
uint112 debtLimit1,
24+
uint256 fee,
25+
uint256 px,
26+
uint256 py,
27+
uint256 cx,
28+
uint256 cy
29+
) internal {
30+
vm.prank(creator);
31+
maglev = new Maglev(
32+
getMaglevBaseParams(debtLimit0, debtLimit1, fee),
33+
Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy})
34+
);
35+
36+
vm.prank(holder);
37+
evc.setAccountOperator(holder, address(maglev), true);
38+
39+
vm.prank(anyone);
40+
maglev.configure();
41+
}
42+
43+
function test_callback() public {
44+
uint256 amountIn = 1e18;
45+
uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn);
46+
assertApproxEqAbs(amountOut, 0.9974e18, 0.0001e18);
47+
48+
assetTST.mint(address(this), amountIn);
49+
assetTST.transfer(address(maglev), amountIn);
50+
51+
uint256 randomBalance = 3e18;
52+
vm.prank(anyone);
53+
swapCallback.executeSwap(maglev, 0, amountOut, abi.encode(randomBalance));
54+
assertEq(assetTST2.balanceOf(address(swapCallback)), amountOut);
55+
assertEq(swapCallback.callbackSender(), address(swapCallback));
56+
assertEq(swapCallback.callbackAmount0(), 0);
57+
assertEq(swapCallback.callbackAmount1(), amountOut);
58+
assertEq(swapCallback.randomBalance(), randomBalance);
59+
}
60+
}
61+
62+
contract SwapCallbackTest is IUniswapV2Callee {
63+
address public callbackSender;
64+
uint256 public callbackAmount0;
65+
uint256 public callbackAmount1;
66+
uint256 public randomBalance;
67+
68+
function executeSwap(Maglev maglev, uint256 amountIn, uint256 amountOut, bytes calldata data) external {
69+
maglev.swap(amountIn, amountOut, address(this), data);
70+
}
71+
72+
function uniswapV2Call(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external {
73+
randomBalance = abi.decode(data, (uint256));
74+
75+
callbackSender = sender;
76+
callbackAmount0 = amount0;
77+
callbackAmount1 = amount1;
78+
}
79+
80+
function test_avoid_coverage() public pure {
81+
return;
82+
}
83+
}

0 commit comments

Comments
 (0)