Skip to content

Commit fb3c1e1

Browse files
committed
move functions from CurveLib into more appropriate places: new CurveExtras library, and tests
1 parent dd99196 commit fb3c1e1

File tree

4 files changed

+48
-37
lines changed

4 files changed

+48
-37
lines changed

docs/architecture.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ The above contracts depend on libraries:
2525
* `FundsLib`: Moving tokens: approvals and transfers in/out
2626
* `CurveLib`: Mathematical routines for calculating the EulerSwap curve
2727
* `QuoteLib`: Computing quotes. This involves invoking the logic from `CurveLib`, as well as taking into account other limitations such as vault utilisation, supply caps, etc.
28+
* `CurveExtrasLib`: Extra utilities for curve computations. Not used in the EulerSwap itself, but potentially useful for integrators.
2829

2930
And some utilities:
3031

src/libraries/CurveExtrasLib.sol

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.27;
3+
4+
import {Math} from "openzeppelin-contracts/utils/math/Math.sol";
5+
6+
library CurveExtrasLib {
7+
/// @dev EulerSwap derivative helper function to find the price after a swap
8+
/// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18
9+
function df_dx(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c)
10+
internal
11+
pure
12+
returns (int256)
13+
{
14+
uint256 r = Math.mulDiv(x0 * x0 / x, 1e18, x, Math.Rounding.Ceil);
15+
return -int256(px * (c + (1e18 - c) * r / 1e18) / py);
16+
}
17+
}

src/libraries/CurveLib.sol

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -116,39 +116,4 @@ library CurveLib {
116116
scale = 1;
117117
}
118118
}
119-
120-
/// @dev Less efficient method to compute fInverse. Useful for testing.
121-
function binarySearch(IEulerSwap.Params memory p, uint256 newReserve1, uint256 xMin, uint256 xMax)
122-
internal
123-
pure
124-
returns (uint256)
125-
{
126-
if (xMin < 1) {
127-
xMin = 1;
128-
}
129-
while (xMin < xMax) {
130-
uint256 xMid = (xMin + xMax) / 2;
131-
uint256 fxMid = f(xMid, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX);
132-
if (newReserve1 >= fxMid) {
133-
xMax = xMid;
134-
} else {
135-
xMin = xMid + 1;
136-
}
137-
}
138-
if (newReserve1 < f(xMin, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX)) {
139-
xMin += 1;
140-
}
141-
return xMin;
142-
}
143-
144-
/// @dev EulerSwap derivative helper function to find the price after a swap
145-
/// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18
146-
function df_dx(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c)
147-
internal
148-
pure
149-
returns (int256)
150-
{
151-
uint256 r = Math.mulDiv(x0 * x0 / x, 1e18, x, Math.Rounding.Ceil);
152-
return -int256(px * (c + (1e18 - c) * r / 1e18) / py);
153-
}
154119
}

test/CurveLib.t.sol

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ contract CurveLibTest is EulerSwapTestBase {
3232

3333
function test_fuzzfInverse(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy)
3434
public
35-
view
35+
pure
3636
{
3737
// Params
3838
px = 1e18;
@@ -72,7 +72,7 @@ contract CurveLibTest is EulerSwapTestBase {
7272
uint256 xCalc = CurveLib.fInverse(y, px, py, x0, y0, cx);
7373
console.log("xCalc", xCalc);
7474
uint256 yCalc = CurveLib.f(xCalc, px, py, x0, y0, cx);
75-
uint256 xBin = CurveLib.binarySearch(p, y, 1, x0);
75+
uint256 xBin = binarySearch(p, y, 1, x0);
7676
uint256 yBin = CurveLib.f(xBin, px, py, x0, y0, cx);
7777
console.log("x ", x);
7878
console.log("xCalc", xCalc);
@@ -86,4 +86,32 @@ contract CurveLibTest is EulerSwapTestBase {
8686
assert(int256(xCalc) - int256(xBin) <= 3 || int256(yCalc) - int256(yBin) <= 3); // suspect this is 2 wei error in fInverse() + 1 wei error in f()
8787
}
8888
}
89+
90+
/// @dev Less efficient method to compute fInverse. Useful for differential fuzzing.
91+
function binarySearch(IEulerSwap.Params memory p, uint256 newReserve1, uint256 xMin, uint256 xMax)
92+
internal
93+
pure
94+
returns (uint256)
95+
{
96+
if (xMin < 1) {
97+
xMin = 1;
98+
}
99+
while (xMin < xMax) {
100+
uint256 xMid = (xMin + xMax) / 2;
101+
uint256 fxMid =
102+
CurveLib.f(xMid, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX);
103+
if (newReserve1 >= fxMid) {
104+
xMax = xMid;
105+
} else {
106+
xMin = xMid + 1;
107+
}
108+
}
109+
if (
110+
newReserve1
111+
< CurveLib.f(xMin, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX)
112+
) {
113+
xMin += 1;
114+
}
115+
return xMin;
116+
}
89117
}

0 commit comments

Comments
 (0)