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/delta params #19

Merged
merged 79 commits into from
Feb 28, 2024
Merged

Feat/delta params #19

merged 79 commits into from
Feb 28, 2024

Conversation

clemlak
Copy link
Contributor

@clemlak clemlak commented Feb 23, 2024

This PR brings a major change in the DFMM contract: when allocating or deallocating liquidity, strategies are no longer expecting the adjusted reserves as parameters but a deltaLiquidity amount along with maximum or minimum deltaX and deltaY amounts that the liquidity provider is willing to pay or expecting to receive.

This change allows multiple liquidity providers to interact with the protocol at the "same time", without having their transactions being invalidated. Also a swap happening before a liquidity change will no longer revert it.

Other changes:

  • Forge was added as a dependency (and is not anymore a dependency of Solstat). This change allows us to benefit from the latests updates of the Forge library.

Closes:

Autoparallel
Autoparallel previously approved these changes Feb 27, 2024
Copy link
Contributor

@Autoparallel Autoparallel left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@@ -89,27 +91,24 @@ contract ConstantSum is IStrategy {
ConstantSumParams memory params =
abi.decode(getPoolParams(poolId), (ConstantSumParams));

(uint256 startRx, uint256 startRy, uint256 startL) =
IDFMM(dfmm).getReservesAndLiquidity(poolId);

(nextRx, nextRy, nextL) = abi.decode(data, (uint256, uint256, uint256));
Copy link
Contributor

Choose a reason for hiding this comment

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

These are really deltaRx, deltaRy and deltaL right?

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like these are still returned to DFMM as next reserves and liquidity

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kinrezC is right, in this case the parameters are still the reserves, I think it's easier because we don't have to think about if the swap is x for y or vice versa.
@Autoparallel I think this is why you were talking about using int256 yesterday? I understand how they could be useful here but I still think they are annoying to deal with.

Anyway, ff we want to use delta we can add a isXForY parameter.

fees = amountIn.mulWadUp(params.swapFee);
minLiquidityDelta += fees.divWadUp(params.price);
} else {
revert("invalid swap: inputs x and y have the same sign!");
}

liquidityDelta = int256(nextL) - int256(startL);
liquidityDelta = int256(nextL) - int256(pool.totalLiquidity);
Copy link
Contributor

Choose a reason for hiding this comment

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

Wait, if we're passing deltas into this method then why are we getting the liquidityDelta here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We're still passing the reserves (see my reply above).

)
{
(reserveX, reserveY, totalLiquidity) =
(deltaX, deltaY, deltaLiquidity) =
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh I see. Only the allocations have the deltas. Perhaps we could also do this with swaps?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it would be better to have all the functions expecting the same kind of parameters.

@@ -41,6 +41,7 @@ contract ConstantSum is IStrategy {
function init(
address,
uint256 poolId,
IDFMM.Pool calldata pool,
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this for?

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, it's not entirely clear to me why we're passing the pool in init, I checked the implementations in all of the strategies and none of them seem to use this argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I explained this on Discord or during a standup, there are two main reasons:

  1. Most of the other functions in IStrategy are receiving the pool parameter, so I added it for the sake of conformity
  2. This extends the possibilities of the strategies, for example restricting the pool creation to stable tokens only, etc...

kinrezC
kinrezC previously approved these changes Feb 27, 2024
Copy link
Contributor

@kinrezC kinrezC left a comment

Choose a reason for hiding this comment

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

LGTM, only nit is that it doesn't seem like we need the pool arg in IDFMM.init

@@ -41,6 +41,7 @@ contract ConstantSum is IStrategy {
function init(
address,
uint256 poolId,
IDFMM.Pool calldata pool,
Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, it's not entirely clear to me why we're passing the pool in init, I checked the implementations in all of the strategies and none of them seem to use this argument.

@@ -89,27 +91,24 @@ contract ConstantSum is IStrategy {
ConstantSumParams memory params =
abi.decode(getPoolParams(poolId), (ConstantSumParams));

(uint256 startRx, uint256 startRy, uint256 startL) =
IDFMM(dfmm).getReservesAndLiquidity(poolId);

(nextRx, nextRy, nextL) = abi.decode(data, (uint256, uint256, uint256));
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like these are still returned to DFMM as next reserves and liquidity

@0xJepsen
Copy link
Contributor

Only comment is that keeping solver function signatures similar across strategies would be nice dev ex for the kit.

@kinrezC kinrezC dismissed stale reviews from Autoparallel and themself via 79141cf February 27, 2024 21:31
@clemlak clemlak added the 📃 contracts Anything related to the DFMM contracts (or strategies) label Feb 28, 2024
@0xJepsen 0xJepsen merged commit 5a9295a into main Feb 28, 2024
5 checks passed
@0xJepsen 0xJepsen deleted the feat/delta-params branch February 28, 2024 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📃 contracts Anything related to the DFMM contracts (or strategies) 💡 feature New features 🧹 improvement Code improvements or cleanup
Projects
None yet
4 participants