Skip to content

Commit f7259ff

Browse files
committed
wip
1 parent 7a31a7f commit f7259ff

File tree

2 files changed

+192
-0
lines changed

2 files changed

+192
-0
lines changed

src/MaglevEulerSwap.sol

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.0;
3+
4+
import {console} from "forge-std/Test.sol";
5+
import {MaglevBase} from "./MaglevBase.sol";
6+
7+
contract MaglevEulerSwap is MaglevBase {
8+
9+
error KNotSatisfied();
10+
11+
struct EulerSwapParams {
12+
uint256 junk;
13+
}
14+
15+
constructor(BaseParams memory baseParams, EulerSwapParams memory params) MaglevBase(baseParams) {
16+
setEulerSwapParams(params);
17+
}
18+
19+
function setEulerSwapParams(EulerSwapParams memory params) public onlyOwner {
20+
}
21+
22+
function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1)
23+
internal
24+
view
25+
virtual
26+
override
27+
{
28+
uint256 px = 1e18;
29+
uint256 py = 1e18;
30+
uint256 cx = 0.40e18;
31+
uint256 cy = 0.85e18;
32+
require(_verify(newReserve0, newReserve1, px, py, virtualReserve0, virtualReserve1, cx, cy), KNotSatisfied());
33+
}
34+
35+
function computeQuote(uint256, bool, bool)
36+
internal
37+
view
38+
virtual
39+
override
40+
returns (uint256)
41+
{
42+
return 0;
43+
}
44+
45+
46+
47+
/////
48+
49+
function fx(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){
50+
require(xt > 0, "Reserves must be greater than zero");
51+
if (xt <= x0) {
52+
return fx1(xt, px, py, x0, y0, cx, cy);
53+
} else {
54+
return fx2(xt, px, py, x0, y0, cx, cy);
55+
}
56+
}
57+
58+
function fx1(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){
59+
require(xt <= x0, "Invalid input coordinate");
60+
return y0 + px * 1e18 / py * (cx * (2 * x0 - xt) / 1e18 + (1e18 - cx) * x0 / 1e18 * x0 / xt - x0) / 1e18;
61+
}
62+
63+
function fx2(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){
64+
require(xt > x0, "Invalid input coordinate");
65+
// intermediate values for solving quadratic equation
66+
uint a = cy;
67+
int b = (int(px) * 1e18 / int(py)) * (int(xt) - int(x0)) / 1e18 + int(y0) * (1e18 - 2 * int(cy)) / 1e18;
68+
int c = (int(cy) - 1e18) * int(y0)**2 / 1e18 / 1e18;
69+
uint discriminant = uint(int(uint(b**2) / 1e18) - 4 * int(a) * int(c) / 1e18);
70+
uint numerator = uint(-b + int(uint(sqrt(discriminant) * 1e9)));
71+
uint denominator = 2 * a;
72+
return numerator * 1e18 / denominator;
73+
}
74+
75+
function fy(uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){
76+
require(yt > 0, "Reserves must be greater than zero");
77+
if (yt <= y0) {
78+
return fx1(yt, py, px, y0, x0, cy, cx);
79+
} else {
80+
return fx2(yt, py, px, y0, x0, cy, cx);
81+
}
82+
}
83+
84+
85+
function swap(int dx, int dy, uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (int, int) {
86+
int xtNew = int(xt);
87+
int ytNew = int(yt);
88+
89+
if (dx != 0) {
90+
xtNew += dx;
91+
ytNew = int(fx(uint(xtNew), px, py, x0, y0, cx, cy));
92+
}
93+
if (dy != 0) {
94+
ytNew += dy;
95+
xtNew = int(fy(uint(ytNew), px, py, x0, y0, cx, cy));
96+
}
97+
dx = xtNew - int(xt);
98+
dy = ytNew - int(yt);
99+
100+
// // check invariant
101+
// let invariantPassed = invariantCheck(xtNew, ytNew, parameters);
102+
103+
return (dx, dy);
104+
}
105+
106+
function _verify(uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (bool){
107+
bool passed = false;
108+
int delta = 0;
109+
if(xt >= x0) {
110+
delta = int(xt) - int(fy(yt, px, py, x0, y0, cx, cy));
111+
console.log("xt: ", int(xt));
112+
console.log("fy: ", int(fy(yt, px, py, x0, y0, cx, cy)));
113+
} else {
114+
delta = int(yt) - int(fx(xt, px, py, x0, y0, cx, cy));
115+
console.log("yt: ", int(yt));
116+
console.log("fx: ", int(fx(xt, px, py, x0, y0, cx, cy)));
117+
}
118+
119+
if (delta >= 0) {
120+
// if distance is > zero, then point is above the curve, and invariant passes
121+
passed = true;
122+
}
123+
return passed;
124+
}
125+
126+
function sqrt(uint256 x) public pure returns (uint128) {
127+
if (x == 0) return 0;
128+
else{
129+
uint256 xx = x;
130+
uint256 r = 1;
131+
if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; }
132+
if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; }
133+
if (xx >= 0x100000000) { xx >>= 32; r <<= 16; }
134+
if (xx >= 0x10000) { xx >>= 16; r <<= 8; }
135+
if (xx >= 0x100) { xx >>= 8; r <<= 4; }
136+
if (xx >= 0x10) { xx >>= 4; r <<= 2; }
137+
if (xx >= 0x8) { r <<= 1; }
138+
r = (r + x / r) >> 1;
139+
r = (r + x / r) >> 1;
140+
r = (r + x / r) >> 1;
141+
r = (r + x / r) >> 1;
142+
r = (r + x / r) >> 1;
143+
r = (r + x / r) >> 1;
144+
r = (r + x / r) >> 1;
145+
uint256 r1 = x / r;
146+
return uint128 (r < r1 ? r : r1);
147+
}
148+
}
149+
}

test/EulerSwap.t.sol

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
3+
pragma solidity ^0.8.24;
4+
5+
import {Test, console} from "forge-std/Test.sol";
6+
7+
import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol";
8+
import {IEVault} from "evk/EVault/IEVault.sol";
9+
import {MaglevTestBase} from "./MaglevTestBase.t.sol";
10+
11+
import {MaglevEulerSwap as Maglev} from "../src/MaglevEulerSwap.sol";
12+
13+
contract EulerSwapTest is MaglevTestBase {
14+
Maglev public maglev;
15+
16+
function setUp() public virtual override {
17+
super.setUp();
18+
19+
vm.prank(owner);
20+
maglev = new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({junk: 0}));
21+
22+
vm.prank(holder);
23+
evc.setAccountOperator(holder, address(maglev), true);
24+
25+
vm.prank(owner);
26+
maglev.configure();
27+
28+
vm.prank(owner);
29+
maglev.setVirtualReserves(50e18, 50e18);
30+
}
31+
32+
function test_basicSwap() public {
33+
uint256 amountIn = 1e18;
34+
uint256 amountOut = 0.3e18;
35+
36+
assetTST.mint(address(this), amountIn);
37+
38+
assetTST.transfer(address(maglev), amountIn);
39+
maglev.swap(0, amountOut, address(this), "");
40+
41+
assertEq(assetTST2.balanceOf(address(this)), amountOut);
42+
}
43+
}

0 commit comments

Comments
 (0)