Skip to content

Commit 5bff386

Browse files
committed
quoting
1 parent 97cf8e9 commit 5bff386

File tree

2 files changed

+88
-36
lines changed

2 files changed

+88
-36
lines changed

src/MaglevEulerSwap.sol

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,29 @@ import {console} from "forge-std/Test.sol";
55
import {MaglevBase} from "./MaglevBase.sol";
66

77
contract MaglevEulerSwap is MaglevBase {
8+
uint256 public _px;
9+
uint256 public _py;
10+
uint256 public _cx;
11+
uint256 public _cy;
812

913
error KNotSatisfied();
1014

1115
struct EulerSwapParams {
12-
uint256 junk;
16+
uint256 px;
17+
uint256 py;
18+
uint256 cx;
19+
uint256 cy;
1320
}
1421

1522
constructor(BaseParams memory baseParams, EulerSwapParams memory params) MaglevBase(baseParams) {
1623
setEulerSwapParams(params);
1724
}
1825

1926
function setEulerSwapParams(EulerSwapParams memory params) public onlyOwner {
27+
_px = params.px;
28+
_py = params.py;
29+
_cx = params.cx;
30+
_cy = params.cy;
2031
}
2132

2233
function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1)
@@ -25,33 +36,51 @@ contract MaglevEulerSwap is MaglevBase {
2536
virtual
2637
override
2738
{
28-
uint256 px = 1e18;
29-
uint256 py = 1e18;
30-
uint256 cx = 0.40e18;
31-
uint256 cy = 0.85e18;
32-
33-
//require(_verify(49e18, 51e18, px, py, 50e18, 50e18, cx, cy), KNotSatisfied());
34-
35-
console.log("QQ", newReserve0, newReserve1);
36-
console.log("ZZ", initialReserve0, initialReserve1);
37-
require(_verify(newReserve0, newReserve1, px, py, initialReserve0, initialReserve1, cx, cy), KNotSatisfied());
39+
require(verifyCurve(newReserve0, newReserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy), KNotSatisfied());
3840
}
3941

40-
function computeQuote(uint256, bool, bool)
42+
uint256 private constant roundingCompensation = 1.0000000000001e18;
43+
44+
function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput)
4145
internal
4246
view
4347
virtual
4448
override
4549
returns (uint256)
4650
{
47-
return 0;
51+
int dx;
52+
int dy;
53+
54+
if (exactIn) {
55+
if (asset0IsInput) dx = int(amount);
56+
else dy = int(amount);
57+
} else {
58+
if (asset0IsInput) dy = -int(amount);
59+
else dx = -int(amount);
60+
}
61+
62+
(dx, dy) = simulateSwap(dx, dy, reserve0, reserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy);
63+
64+
uint output;
65+
66+
if (exactIn) {
67+
if (asset0IsInput) output = uint(-dy);
68+
else output = uint(-dx);
69+
output = output * 1e18 / roundingCompensation;
70+
} else {
71+
if (asset0IsInput) output = uint(dx);
72+
else output = uint(dy);
73+
output = output * roundingCompensation / 1e18;
74+
}
75+
76+
return output;
4877
}
4978

5079

5180

5281
/////
5382

54-
function fx(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){
83+
function fx(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (uint){
5584
require(xt > 0, "Reserves must be greater than zero");
5685
if (xt <= x0) {
5786
return fx1(xt, px, py, x0, y0, cx, cy);
@@ -60,12 +89,12 @@ contract MaglevEulerSwap is MaglevBase {
6089
}
6190
}
6291

63-
function fx1(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){
92+
function fx1(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint) internal pure returns (uint){
6493
require(xt <= x0, "Invalid input coordinate");
6594
return y0 + px * 1e18 / py * (cx * (2 * x0 - xt) / 1e18 + (1e18 - cx) * x0 / 1e18 * x0 / xt - x0) / 1e18;
6695
}
6796

68-
function fx2(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){
97+
function fx2(uint xt, uint px, uint py, uint x0, uint y0, uint, uint cy) internal pure returns (uint){
6998
require(xt > x0, "Invalid input coordinate");
7099
// intermediate values for solving quadratic equation
71100
uint a = cy;
@@ -77,7 +106,7 @@ contract MaglevEulerSwap is MaglevBase {
77106
return numerator * 1e18 / denominator;
78107
}
79108

80-
function fy(uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){
109+
function fy(uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (uint){
81110
require(yt > 0, "Reserves must be greater than zero");
82111
if (yt <= y0) {
83112
return fx1(yt, py, px, y0, x0, cy, cx);
@@ -87,7 +116,7 @@ contract MaglevEulerSwap is MaglevBase {
87116
}
88117

89118

90-
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) {
119+
function simulateSwap(int dx, int dy, uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (int, int) {
91120
int xtNew = int(xt);
92121
int ytNew = int(yt);
93122

@@ -102,33 +131,24 @@ contract MaglevEulerSwap is MaglevBase {
102131
dx = xtNew - int(xt);
103132
dy = ytNew - int(yt);
104133

105-
// // check invariant
106-
// let invariantPassed = invariantCheck(xtNew, ytNew, parameters);
107-
108134
return (dx, dy);
109135
}
110136

111-
function _verify(uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (bool){
112-
bool passed = false;
137+
function verifyCurve(uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (bool){
113138
int delta = 0;
114-
if(xt >= x0) {
139+
140+
if (xt >= x0) {
115141
delta = int(xt) - int(fy(yt, px, py, x0, y0, cx, cy));
116-
console.log("xt: ", int(xt));
117-
console.log("fy: ", int(fy(yt, px, py, x0, y0, cx, cy)));
118142
} else {
119143
delta = int(yt) - int(fx(xt, px, py, x0, y0, cx, cy));
120-
console.log("yt: ", int(yt));
121-
console.log("fx: ", int(fx(xt, px, py, x0, y0, cx, cy)));
122144
}
123145

124-
if (delta >= 0) {
125-
// if distance is > zero, then point is above the curve, and invariant passes
126-
passed = true;
127-
}
128-
return passed;
146+
// if distance is > zero, then point is above the curve, and invariant passes
147+
return (delta >= 0);
129148
}
130149

131-
function sqrt(uint256 x) public pure returns (uint128) {
150+
// EIP-7054
151+
function sqrt(uint256 x) internal pure returns (uint128) {
132152
if (x == 0) return 0;
133153
else{
134154
uint256 xx = x;

test/EulerSwap.t.sol

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ contract EulerSwapTest is MaglevTestBase {
1717
super.setUp();
1818

1919
vm.prank(owner);
20-
maglev = new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({junk: 0}));
20+
maglev = new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({
21+
px: 1e18,
22+
py: 1e18,
23+
cx: 0.40e18,
24+
cy: 0.85e18
25+
}));
2126

2227
vm.prank(holder);
2328
evc.setAccountOperator(holder, address(maglev), true);
@@ -31,7 +36,7 @@ contract EulerSwapTest is MaglevTestBase {
3136

3237
function test_basicSwap() public {
3338
uint256 amountIn = 1e18;
34-
uint256 amountOut = 0.99e18;
39+
uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn);
3540

3641
assetTST.mint(address(this), amountIn);
3742

@@ -40,4 +45,31 @@ contract EulerSwapTest is MaglevTestBase {
4045

4146
assertEq(assetTST2.balanceOf(address(this)), amountOut);
4247
}
48+
49+
50+
function test_pathIndependent(uint256 amount, bool dir) public {
51+
amount = bound(amount, 0.1e18, 25e18);
52+
53+
TestERC20 t1;
54+
TestERC20 t2;
55+
if (dir) (t1, t2) = (assetTST, assetTST2);
56+
else (t1, t2) = (assetTST2, assetTST);
57+
58+
t1.mint(address(this), amount);
59+
60+
uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount);
61+
62+
t1.transfer(address(maglev), amount);
63+
if (dir) maglev.swap(0, q, address(this), "");
64+
else maglev.swap(q, 0, address(this), "");
65+
assertEq(t2.balanceOf(address(this)), q);
66+
67+
t2.transfer(address(maglev), q);
68+
if (dir) maglev.swap(amount - 2, 0, address(this), ""); // - 2 due to rounding
69+
70+
else maglev.swap(0, amount - 2, address(this), "");
71+
72+
uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount);
73+
assertApproxEqAbs(q, q2, 0.00000001e18);
74+
}
4375
}

0 commit comments

Comments
 (0)