Skip to content

Commit

Permalink
Merge pull request #71 from primitivefinance/fix/lognormal-fees
Browse files Browse the repository at this point in the history
Fixed fee accounting for lognormal strategy
  • Loading branch information
clemlak authored Mar 14, 2024
2 parents f6ec10f + e6ecaee commit 12f2ea4
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 6 deletions.
24 changes: 24 additions & 0 deletions src/LogNormal/LogNormalMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,30 @@ function computePriceGivenY(
return params.mean.mulWadUp(uint256(exp));
}

function computeDeltaLXIn(
uint256 amountIn,
uint256 rx,
uint256 ry,
uint256 L,
LogNormalParams memory params
) pure returns (uint256 deltaL) {
uint256 fees = params.swapFee.mulWadUp(amountIn);
uint256 px = computePriceGivenX(rx, L, params);
deltaL = px.mulWadUp(L).mulWadUp(fees).divWadDown(px.mulWadDown(rx) + ry);
}

function computeDeltaLYIn(
uint256 amountIn,
uint256 rx,
uint256 ry,
uint256 L,
LogNormalParams memory params
) pure returns (uint256 deltaL) {
uint256 fees = params.swapFee.mulWadUp(amountIn);
uint256 px = computePriceGivenX(rx, L, params);
deltaL = L.mulWadUp(fees).divWadDown(px.mulWadDown(rx) + ry);
}

/// @dev This is a pure anonymous function defined at the file level, which allows
/// it to be passed as an argument to another function. BisectionLib.sol takes this
/// function as an argument to find the root of the trading function given the reserveYWad.
Expand Down
21 changes: 17 additions & 4 deletions src/LogNormal/LogNormalSolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ import {
computeYGivenL,
computeNextRy,
computePriceGivenX,
computePriceGivenY
computePriceGivenY,
computeDeltaLXIn,
computeDeltaLYIn
} from "src/LogNormal/LogNormalMath.sol";

contract LogNormalSolver {
Expand Down Expand Up @@ -254,7 +256,13 @@ contract LogNormalSolver {
);

if (swapXIn) {
state.deltaLiquidity = amountIn.mulWadUp(poolParams.swapFee);
state.deltaLiquidity = computeDeltaLXIn(
amountIn,
preReserves[0],
preReserves[1],
preTotalLiquidity,
poolParams
);

endReserves.rx = preReserves[0] + amountIn;
endReserves.L = startComputedL + state.deltaLiquidity;
Expand All @@ -271,8 +279,13 @@ contract LogNormalSolver {
);
state.amountOut = preReserves[1] - endReserves.ry;
} else {
state.deltaLiquidity = amountIn.mulWadUp(poolParams.swapFee)
.divWadUp(poolParams.mean);
state.deltaLiquidity = computeDeltaLYIn(
amountIn,
preReserves[0],
preReserves[1],
preTotalLiquidity,
poolParams
);

endReserves.ry = preReserves[1] + amountIn;
endReserves.L = startComputedL + state.deltaLiquidity;
Expand Down
35 changes: 35 additions & 0 deletions test/LogNormal/unit/SetUp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,24 @@ contract LogNormalSetUp is SetUp {
controller: address(this)
});

LogNormalParams defaultParamsDeep = LogNormalParams({
mean: ONE,
width: 0.25 ether,
swapFee: TEST_SWAP_FEE,
controller: address(this)
});

uint256 defaultReserveX = ONE;
uint256 defaultReserveXDeep = ONE * 10_000_000;

uint256 defaultPrice = ONE;
bytes defaultInitialPoolData =
computeInitialPoolData(defaultReserveX, defaultPrice, defaultParams);

bytes defaultInitialPoolDataDeep = computeInitialPoolData(
defaultReserveXDeep, defaultPrice, defaultParamsDeep
);

function setUp() public override {
SetUp.setUp();
logNormal = new LogNormal(address(dfmm));
Expand Down Expand Up @@ -52,6 +65,28 @@ contract LogNormalSetUp is SetUp {
_;
}

modifier deep() {
vm.warp(0);

address[] memory tokens = new address[](2);
tokens[0] = address(tokenX);
tokens[1] = address(tokenY);

InitParams memory defaultInitParamsDeep = InitParams({
name: "",
symbol: "",
strategy: address(logNormal),
tokens: tokens,
data: defaultInitialPoolDataDeep,
feeCollector: address(0),
controllerFee: 0
});

(POOL_ID,,) = dfmm.init(defaultInitParamsDeep);

_;
}

modifier initRealistic() {
vm.warp(0);

Expand Down
29 changes: 29 additions & 0 deletions test/LogNormal/unit/Swap.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,33 @@ contract LogNormalSwapTest is LogNormalSetUp {
vm.expectRevert();
dfmm.swap(POOL_ID, payload);
}
function test_LogNormal_swap_ChargesCorrectFeesYIn() public deep {
uint256 amountIn = 1 ether;
bool swapXForY = false;

(bool valid,,, bytes memory payload) =
solver.simulateSwap(POOL_ID, swapXForY, amountIn);

(,, uint256 inputAmount, uint256 outputAmount) =
dfmm.swap(POOL_ID, payload);

console2.log(inputAmount);
console2.log(outputAmount);

}

function test_LogNormal_swap_ChargesCorrectFeesXIn() public deep {
uint256 amountIn = 1 ether;
bool swapXForY = true;

(bool valid,,, bytes memory payload) =
solver.simulateSwap(POOL_ID, swapXForY, amountIn);

(,, uint256 inputAmount, uint256 outputAmount) =
dfmm.swap(POOL_ID, payload);

console2.log(inputAmount);
console2.log(outputAmount);

}
}
4 changes: 2 additions & 2 deletions test/utils/SetUp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ contract SetUp is Test {
function setUp() public virtual {
tokenX = new MockERC20("Test Token X", "TSTX", 18);
tokenY = new MockERC20("Test Token Y", "TSTY", 18);
tokenX.mint(address(this), 100_000e18);
tokenY.mint(address(this), 100_000e18);
tokenX.mint(address(this), 10_000_000_000_000e18);
tokenY.mint(address(this), 10_000_000_000_000e18);

weth = new WETH();
dfmm = new DFMM(address(weth));
Expand Down

0 comments on commit 12f2ea4

Please sign in to comment.