Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Solvers clean #116

Closed
wants to merge 9 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/ConstantSum/ConstantSumMath.sol
Original file line number Diff line number Diff line change
@@ -50,3 +50,10 @@ function computeSwapDeltaLiquidity(
return (params.swapFee).mulDivUp(delta, params.price);
}
}

/**
* @dev Computes the price using the reserve of token X.
*/
function computePrice(ConstantSumParams memory params) pure returns (uint256) {
return params.price;
}
Comment on lines +57 to +59
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this one is needed? I understand that it might be for consistency regarding the other strategies but I think this one could just be an exception.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really but makes the api the same between them all. I think general is better than bespoke so i advocate for keeping it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this, but if it lives in the ConstantSumMath.sol and it's not invoked anywhere in e.g. solver, or strategy it doesn't really do anything, so I'm not sure what to do with this at the moment.

102 changes: 95 additions & 7 deletions src/ConstantSum/ConstantSumSolver.sol
Original file line number Diff line number Diff line change
@@ -9,43 +9,69 @@ import {
encodeFeeUpdate,
encodeControllerUpdate
} from "./ConstantSumUtils.sol";
import {
computeAllocationGivenX,
computeAllocationGivenY
} from "src/lib/StrategyLib.sol";
import {
ONE,
computeInitialPoolData,
FixedPointMathLib,
computeSwapDeltaLiquidity
} from "./ConstantSumMath.sol";
import { PairSolver } from "src/PairSolver.sol";

contract ConstantSumSolver {
contract ConstantSumSolver is PairSolver {
error NotEnoughLiquidity();

using FixedPointMathLib for uint256;

/// @dev Reserves struct to hold reserve amounts and liquidity
struct Reserves {
uint256 rx;
uint256 ry;
uint256 L;
uint256 reserveX;
/// @dev Reserve amount of token X
uint256 reserveY;
/// @dev Reserve amount of token Y
uint256 liquidity;
}
/// @dev Total liquidity

/// @dev Address of the strategy contract
address public strategy;

/// @notice Constructor to set the strategy address
/// @param strategy_ Address of the strategy contract
constructor(address strategy_) {
strategy = strategy_;
}

/// @notice Computes the initial pool data for a Constant Sum pool
/// @param reserveX The reserve amount of token X
/// @param reserveY The reserve amount of token Y
/// @param params The Constant Sum pool parameters
/// @return The initial pool data encoded as bytes
function getInitialPoolData(
uint256 rx,
uint256 ry,
uint256 reserveX,
uint256 reserveY,
ConstantSumParams memory params
) public pure returns (bytes memory) {
return computeInitialPoolData(rx, ry, params);
return computeInitialPoolData(reserveX, reserveY, params);
}

/// @dev Struct to hold state variables for simulating a swap
struct SimulateSwapState {
uint256 amountOut;
uint256 deltaLiquidity;
}

/// @notice Simulates a swap in a Constant Sum pool
/// @dev Used by the kit to simulate a swap and check if it's valid
/// @param poolId The id of the pool to simulate the swap in
/// @param swapXIn Whether the swap is X in for Y out (true) or Y in for X out (false)
/// @param amountIn The amount of tokens to swap in
/// @return valid Whether the simulated swap is valid
/// @return amountOut The amount of tokens that would be received in the swap
/// @return swapData The encoded swap data that can be used to perform the actual swap
function simulateSwap(
uint256 poolId,
bool swapXIn,
@@ -91,6 +117,10 @@ contract ConstantSumSolver {
return (valid, state.amountOut, swapData);
}

/// @notice Prepares the data for updating the price
/// @dev Used by the kit to update the price
/// @param newPrice The new price to set
/// @return The encoded data for updating the price
function preparePriceUpdate(uint256 newPrice)
public
pure
@@ -99,6 +129,10 @@ contract ConstantSumSolver {
return encodePriceUpdate(newPrice);
}

/// @notice Prepares the data for updating the swap fee
/// @dev Used by the kit to update the swap fee
/// @param newSwapFee The new swap fee to set
/// @return The encoded data for updating the swap fee
function prepareSwapFeeUpdate(uint256 newSwapFee)
public
pure
@@ -107,11 +141,65 @@ contract ConstantSumSolver {
return encodeFeeUpdate(newSwapFee);
}

/// @notice Prepares the data for updating the controller address
/// @dev Used by the kit to update the controller
/// @param newController The address of the new controller
/// @return The encoded data for updating the controller
function prepareControllerUpdate(address newController)
public
pure
returns (bytes memory)
{
return encodeControllerUpdate(newController);
}

/// @notice Gets the reserves and liquidity for a given pool
/// @param poolId The id of the pool
/// @return The reserve of token X, the reserve of token Y, and the total liquidity
function getReservesAndLiquidity(uint256 poolId)
public
view
override
returns (uint256, uint256, uint256)
{
Pool memory pool = IDFMM(IStrategy(strategy).dfmm()).pools(poolId);
return (pool.reserves[0], pool.reserves[1], pool.totalLiquidity);
}

/// @dev gets the pool params
/// @param poolId The pool id
/// @return params The pool params
function getPoolParams(uint256 poolId)
public
view
returns (ConstantSumParams memory)
{
return abi.decode(
IStrategy(strategy).getPoolParams(poolId), (ConstantSumParams)
);
}

/// @dev Computes the change in allocation given a change in X reserve
/// @param poolId The pool id
/// @param deltaX The change in X reserve
/// @return encodedAllocationDelta The encoded change in allocation
function prepareAllocationDeltaGivenDeltaX(
uint256 poolId,
uint256 deltaX
) public view returns (bytes memory) {
ConstantSumParams memory params = getPoolParams(poolId);
uint256 deltaL = deltaX.mulWadDown(params.price);
return abi.encode(deltaX, 0, deltaL);
}

/// @dev Computes the change in allocation given a change in Y reserve
/// @param deltaY The change in Y reserve
/// @return encodedAllocationDelta The encoded change in allocation
function prepareAllocationDeltaGivenDeltaY(uint256 deltaY)
public
pure
returns (bytes memory)
{
return abi.encode(0, deltaY, deltaY);
}
}
2 changes: 1 addition & 1 deletion src/ConstantSum/README.md
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ $$
where $L$ is the **liquidity** of the pool.

## Price
The reported price of the pool given the reseres is $P$.
The reported price of the pool given the reserves is $P$.

## Pool initialization
The `ConstantSum` pool can be initialized with any given price and any given value of reserves.
48 changes: 3 additions & 45 deletions src/GeometricMean/GeometricMeanSolver.sol
Original file line number Diff line number Diff line change
@@ -22,8 +22,9 @@ import {
computePrice,
computeSwapDeltaLiquidity
} from "./G3MMath.sol";
import { PairSolver } from "src/PairSolver.sol";

contract GeometricMeanSolver {
contract GeometricMeanSolver is PairSolver {
using FixedPointMathLib for uint256;
using FixedPointMathLib for int256;

@@ -46,6 +47,7 @@ contract GeometricMeanSolver {
function getReservesAndLiquidity(uint256 poolId)
public
view
override
returns (uint256, uint256, uint256)
{
Pool memory pool = IDFMM(IStrategy(strategy).dfmm()).pools(poolId);
@@ -94,50 +96,6 @@ contract GeometricMeanSolver {
return computeInitialPoolData(rx, S, params);
}

function allocateGivenDeltaX(
uint256 poolId,
uint256 deltaX
) public view returns (uint256, uint256) {
(uint256 rX, uint256 rY, uint256 totalLiquidity) =
getReservesAndLiquidity(poolId);
(uint256 deltaY, uint256 deltaLiquidity) =
computeAllocationGivenDeltaX(deltaX, rX, rY, totalLiquidity);
return (deltaY, deltaLiquidity);
}

function allocateGivenDeltaY(
uint256 poolId,
uint256 deltaY
) public view returns (uint256, uint256) {
(uint256 rX, uint256 rY, uint256 totalLiquidity) =
getReservesAndLiquidity(poolId);
(uint256 deltaX, uint256 deltaLiquidity) =
computeAllocationGivenDeltaY(deltaY, rX, rY, totalLiquidity);
return (deltaX, deltaLiquidity);
}

function deallocateGivenDeltaX(
uint256 poolId,
uint256 deltaX
) public view returns (uint256, uint256) {
(uint256 rX, uint256 rY, uint256 totalLiquidity) =
getReservesAndLiquidity(poolId);
(uint256 deltaY, uint256 deltaLiquidity) =
computeDeallocationGivenDeltaX(deltaX, rX, rY, totalLiquidity);
return (deltaY, deltaLiquidity);
}

function deallocateGivenDeltaY(
uint256 poolId,
uint256 deltaY
) public view returns (uint256, uint256) {
(uint256 rX, uint256 rY, uint256 totalLiquidity) =
getReservesAndLiquidity(poolId);
(uint256 deltaX, uint256 deltaLiquidity) =
computeDeallocationGivenDeltaY(deltaY, rX, rY, totalLiquidity);
return (deltaX, deltaLiquidity);
}

function getNextReserveX(
uint256 poolId,
uint256 ry,
Loading
Loading