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

Flip the sign of deltas #481

Merged
merged 31 commits into from
Mar 13, 2024
Merged

Flip the sign of deltas #481

merged 31 commits into from
Mar 13, 2024

Conversation

hensha256
Copy link
Contributor

@hensha256 hensha256 commented Feb 14, 2024

closes #467

The current set up is counter intuitive.

After this pull request:

  • as positive delta means that the address can withdraw money from the pool manager
  • withdrawing money will subtract from the delta.
  • a negative delta means that the address owes the pool manager
  • sending money into the PM will add to the delta.

src/PoolManager.sol Outdated Show resolved Hide resolved
@ewilz
Copy link
Member

ewilz commented Feb 21, 2024

I realize this is potentially a can of worms w swap math + backwards compatibility, but does a negative amountSpecified make more sense to denote amountIn now (negative for the user)?

Base automatically changed from remove-nested-locks to main February 29, 2024 01:22
@hensha256 hensha256 linked an issue Mar 5, 2024 that may be closed by this pull request
src/PoolManager.sol Outdated Show resolved Hide resolved
src/PoolManager.sol Outdated Show resolved Hide resolved
src/libraries/Pool.sol Outdated Show resolved Hide resolved
src/libraries/Pool.sol Outdated Show resolved Hide resolved
src/libraries/Pool.sol Outdated Show resolved Hide resolved
src/test/PoolTestBase.sol Show resolved Hide resolved
src/test/PoolTestBase.sol Show resolved Hide resolved
test/utils/SwapHelper.t.sol Outdated Show resolved Hide resolved
hensha256 and others added 2 commits March 6, 2024 14:47
Co-authored-by: hensha256 <henshawalice@gmail.com>
src/PoolManager.sol Outdated Show resolved Hide resolved
src/PoolManager.sol Outdated Show resolved Hide resolved
src/test/PoolSwapTest.sol Outdated Show resolved Hide resolved
src/libraries/Pool.sol Outdated Show resolved Hide resolved
ewilz
ewilz previously approved these changes Mar 7, 2024
Copy link
Member

@ewilz ewilz left a comment

Choose a reason for hiding this comment

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

approved with some nits about code comments

@@ -200,8 +200,8 @@ library SqrtPriceMath {
{
unchecked {
return liquidity < 0
Copy link
Member

Choose a reason for hiding this comment

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

Are we sure we don't want to switch liquidityDelta sign if we are changing amountSpecified sign? Now they don't match right?

IE liquidityDelta is positive, we return negative delta because user owes $ to pool and if liquidityDelta is negative (user is taking liquidity out of the pool) we return a positive delta because the user can now claim it back from the pool...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right the argument is that liquidityDelta is the user's delta of liquidity units not token units. When they pass in liquidityDelta = 100 its because they want their liquidity balance to increase by 100 (which means sending tokens into the contract). So liquidityDelta is in line with amountSpecified now... for both of them:

  • positive: the balance of the thing in question goes up
  • negative: the balance of the thing in question goes down

Copy link
Member

Choose a reason for hiding this comment

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

great, makes sense! i think im in agreement w that framing then

}

if (exactIn && sqrtRatioNextX96 != sqrtRatioTargetX96) {
// we didn't reach the target, so take the remainder of the maximum input as fee
feeAmount = uint256(amountRemaining) - amountIn;
feeAmount = uint256(-amountRemaining) - amountIn;
Copy link
Member

Choose a reason for hiding this comment

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

I think I'm not 100% understanding this line. If we have't reached the target the feeAmount is the amount left to swap minus the amount already swapped?

Also why does this case only happen in the exactIn case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we have't reached the target the feeAmount is the amount left to swap minus the amount already swapped?

If we havent reached the target (which is the essentially maximum slippage where the trade has to stop), that means that all of the amountRemaining has successfully be traded into output tokens. The case this happens, the function follows the following flow...

  • calculate amountRemainingLessFee which is just the amount to be traded, minus the LP fee
  • calculates the sqrtRatioNextX96 that does get reached by this amount of input tokens
  • calculate the exact amountIn needed to trade to that next sqrtRatio using getAmount0Delta. Due to rounding of calculations this could be slightly different to the amountRemainingLessFee that it was going to trade before
  • now the true LP fee amount needs to be calculated, which is the difference between the total amount to be traded amountRemaining (which is now negative so needs to be flipped), and amountIn which is the amount thats actually being swapped. This means that the fee is rounded in the LP's favour.

Also why does this case only happen in the exactIn case?

LP fees are taken on input tokens. For exactIn, the calculation makes sure that the final amountIn including fees is amountRemaining. For non-exactIn the fee amount can just be calculated as feePips% of the amountIn, again rounded in the LP's favour. Theres not a need to make sure that the total feeAmount + amountIn == amountRemaining because its not exactIn so the "exact" part stops mattering

src/test/PoolTestBase.sol Show resolved Hide resolved
@@ -249,7 +249,7 @@ contract SqrtPriceMathTestTest is Test, GasSnapshot {
assertEq(amount0, 0);
}

function test_getAmount0Delta_returns0_1Amount1ForPriceOf1To1_21() public {
function test_getAmount0Delta_1Amount1ForPriceOf1To1_21() public {
Copy link
Member

Choose a reason for hiding this comment

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

hm I know not your change but what is 1Amount1? Not really sure what this is testing/what the change to the name means

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 tests getAmount0Delta, with an amount1 of 1, and a price of SQRT_RATIO_121_100.
I removed the return0 because it doesnt test that (i think it was copied from the test name above)

Copy link
Member

Choose a reason for hiding this comment

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

sounds good

@saucepoint saucepoint mentioned this pull request Mar 13, 2024
@snreynolds snreynolds self-requested a review March 13, 2024 20:29
@hensha256 hensha256 merged commit b5b3614 into main Mar 13, 2024
5 checks passed
@hensha256 hensha256 deleted the flip-the-deltas branch March 13, 2024 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Flip the sign on currencyDeltas and accountDelta
3 participants