From 5c1c67bf73c538c0783cd9f7d94ed7d041a48c31 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Sun, 30 Jun 2024 15:49:00 -0400 Subject: [PATCH] fix: accrue deltas to caller in increase --- .forge-snapshots/autocompound_exactUnclaimedFees.snap | 2 +- ...ompound_exactUnclaimedFees_exactCustodiedFees.snap | 2 +- .forge-snapshots/autocompound_excessFeesCredit.snap | 2 +- .forge-snapshots/decreaseLiquidity_erc20.snap | 2 +- .forge-snapshots/decreaseLiquidity_erc6909.snap | 2 +- .forge-snapshots/increaseLiquidity_erc20.snap | 2 +- .forge-snapshots/increaseLiquidity_erc6909.snap | 2 +- .forge-snapshots/mintWithLiquidity.snap | 2 +- contracts/NonfungiblePositionManager.sol | 11 ++++++++--- contracts/base/BaseLiquidityManagement.sol | 6 +++++- contracts/libraries/TransientLiquidityDelta.sol | 6 +++++- 11 files changed, 26 insertions(+), 13 deletions(-) diff --git a/.forge-snapshots/autocompound_exactUnclaimedFees.snap b/.forge-snapshots/autocompound_exactUnclaimedFees.snap index 7e227334..8dd96b22 100644 --- a/.forge-snapshots/autocompound_exactUnclaimedFees.snap +++ b/.forge-snapshots/autocompound_exactUnclaimedFees.snap @@ -1 +1 @@ -299999 \ No newline at end of file +300126 \ No newline at end of file diff --git a/.forge-snapshots/autocompound_exactUnclaimedFees_exactCustodiedFees.snap b/.forge-snapshots/autocompound_exactUnclaimedFees_exactCustodiedFees.snap index eba79610..f9df8100 100644 --- a/.forge-snapshots/autocompound_exactUnclaimedFees_exactCustodiedFees.snap +++ b/.forge-snapshots/autocompound_exactUnclaimedFees_exactCustodiedFees.snap @@ -1 +1 @@ -239461 \ No newline at end of file +239588 \ No newline at end of file diff --git a/.forge-snapshots/autocompound_excessFeesCredit.snap b/.forge-snapshots/autocompound_excessFeesCredit.snap index 1de65bbc..eed2bed5 100644 --- a/.forge-snapshots/autocompound_excessFeesCredit.snap +++ b/.forge-snapshots/autocompound_excessFeesCredit.snap @@ -1 +1 @@ -320538 \ No newline at end of file +320665 \ No newline at end of file diff --git a/.forge-snapshots/decreaseLiquidity_erc20.snap b/.forge-snapshots/decreaseLiquidity_erc20.snap index 5b2a6a2d..5e4cd19e 100644 --- a/.forge-snapshots/decreaseLiquidity_erc20.snap +++ b/.forge-snapshots/decreaseLiquidity_erc20.snap @@ -1 +1 @@ -215178 \ No newline at end of file +215187 \ No newline at end of file diff --git a/.forge-snapshots/decreaseLiquidity_erc6909.snap b/.forge-snapshots/decreaseLiquidity_erc6909.snap index 6be588c8..e21ae2c4 100644 --- a/.forge-snapshots/decreaseLiquidity_erc6909.snap +++ b/.forge-snapshots/decreaseLiquidity_erc6909.snap @@ -1 +1 @@ -215190 \ No newline at end of file +215199 \ No newline at end of file diff --git a/.forge-snapshots/increaseLiquidity_erc20.snap b/.forge-snapshots/increaseLiquidity_erc20.snap index f425bf00..37a69b54 100644 --- a/.forge-snapshots/increaseLiquidity_erc20.snap +++ b/.forge-snapshots/increaseLiquidity_erc20.snap @@ -1 +1 @@ -194902 \ No newline at end of file +195029 \ No newline at end of file diff --git a/.forge-snapshots/increaseLiquidity_erc6909.snap b/.forge-snapshots/increaseLiquidity_erc6909.snap index 9e4b89f3..23ce9120 100644 --- a/.forge-snapshots/increaseLiquidity_erc6909.snap +++ b/.forge-snapshots/increaseLiquidity_erc6909.snap @@ -1 +1 @@ -194914 \ No newline at end of file +195041 \ No newline at end of file diff --git a/.forge-snapshots/mintWithLiquidity.snap b/.forge-snapshots/mintWithLiquidity.snap index d9ae28af..39d02c26 100644 --- a/.forge-snapshots/mintWithLiquidity.snap +++ b/.forge-snapshots/mintWithLiquidity.snap @@ -1 +1 @@ -511702 \ No newline at end of file +512049 \ No newline at end of file diff --git a/contracts/NonfungiblePositionManager.sol b/contracts/NonfungiblePositionManager.sol index 83209155..594e4997 100644 --- a/contracts/NonfungiblePositionManager.sol +++ b/contracts/NonfungiblePositionManager.sol @@ -20,6 +20,8 @@ import {TransientStateLibrary} from "@uniswap/v4-core/src/libraries/TransientSta import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; import {TransientLiquidityDelta} from "./libraries/TransientLiquidityDelta.sol"; +import "forge-std/console2.sol"; + contract NonfungiblePositionManager is INonfungiblePositionManager, BaseLiquidityManagement, ERC721Permit { using CurrencyLibrary for Currency; using CurrencySettleTake for Currency; @@ -39,12 +41,18 @@ contract NonfungiblePositionManager is INonfungiblePositionManager, BaseLiquidit // TODO: TSTORE this jawn address internal msgSender; + // TODO: Context is inherited through ERC721 and will be not useful to use _msgSender() which will be address(this) with our current mutlicall. + function _msgSenderInternal() internal override returns (address) { + return msgSender; + } + constructor(IPoolManager _manager) BaseLiquidityManagement(_manager) ERC721Permit("Uniswap V4 Positions NFT-V1", "UNI-V4-POS", "1") {} function unlockAndExecute(bytes[] memory data, Currency[] memory currencies) public returns (bytes memory) { + msgSender = msg.sender; return manager.unlock(abi.encode(data, currencies)); } @@ -134,7 +142,6 @@ contract NonfungiblePositionManager is INonfungiblePositionManager, BaseLiquidit if (manager.isUnlocked()) { _increaseLiquidity(tokenPos.owner, tokenPos.range, liquidity, hookData); } else { - msgSender = msg.sender; bytes[] memory data = new bytes[](1); data[0] = abi.encodeWithSelector(this.increaseLiquidity.selector, tokenId, liquidity, hookData, claims); @@ -156,7 +163,6 @@ contract NonfungiblePositionManager is INonfungiblePositionManager, BaseLiquidit if (manager.isUnlocked()) { _decreaseLiquidity(tokenPos.owner, tokenPos.range, liquidity, hookData); } else { - msgSender = msg.sender; bytes[] memory data = new bytes[](1); data[0] = abi.encodeWithSelector(this.decreaseLiquidity.selector, tokenId, liquidity, hookData, claims); @@ -189,7 +195,6 @@ contract NonfungiblePositionManager is INonfungiblePositionManager, BaseLiquidit if (manager.isUnlocked()) { _collect(recipient, tokenPos.range, hookData); } else { - msgSender = msg.sender; bytes[] memory data = new bytes[](1); data[0] = abi.encodeWithSelector(this.collect.selector, tokenId, recipient, hookData, claims); diff --git a/contracts/base/BaseLiquidityManagement.sol b/contracts/base/BaseLiquidityManagement.sol index fcd3b593..c1c1308b 100644 --- a/contracts/base/BaseLiquidityManagement.sol +++ b/contracts/base/BaseLiquidityManagement.sol @@ -49,6 +49,8 @@ abstract contract BaseLiquidityManagement is IBaseLiquidityManagement, SafeCallb constructor(IPoolManager _manager) ImmutableState(_manager) {} + function _msgSenderInternal() internal virtual returns (address); + function _closeCallerDeltas( BalanceDelta callerDeltas, Currency currency0, @@ -120,7 +122,9 @@ abstract contract BaseLiquidityManagement is IBaseLiquidityManagement, SafeCallb (tokensOwed, callerDelta, thisDelta) = _moveCallerDeltaToTokensOwed(false, tokensOwed, callerDelta, thisDelta); } - callerDelta.flush(owner, range.poolKey.currency0, range.poolKey.currency1); + + // Accrue all deltas to the caller. + callerDelta.flush(_msgSenderInternal(), range.poolKey.currency0, range.poolKey.currency1); thisDelta.flush(address(this), range.poolKey.currency0, range.poolKey.currency1); position.addTokensOwed(tokensOwed); diff --git a/contracts/libraries/TransientLiquidityDelta.sol b/contracts/libraries/TransientLiquidityDelta.sol index 86f85c85..9dca43a5 100644 --- a/contracts/libraries/TransientLiquidityDelta.sol +++ b/contracts/libraries/TransientLiquidityDelta.sol @@ -6,11 +6,15 @@ import {BalanceDelta, toBalanceDelta} from "@uniswap/v4-core/src/types/BalanceDe import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {CurrencySettleTake} from "../libraries/CurrencySettleTake.sol"; +import {TransientStateLibrary} from "@uniswap/v4-core/src/libraries/TransientStateLibrary.sol"; + +import "forge-std/console2.sol"; /// @title a library to store callers' currency deltas in transient storage /// @dev this library implements the equivalent of a mapping, as transient storage can only be accessed in assembly library TransientLiquidityDelta { using CurrencySettleTake for Currency; + using TransientStateLibrary for IPoolManager; /// @notice calculates which storage slot a delta should be stored in for a given caller and currency function _computeSlot(address caller_, Currency currency) internal pure returns (bytes32 hashSlot) { @@ -58,7 +62,7 @@ library TransientLiquidityDelta { delta := tload(hashSlot) } - // close the delta by paying or taking + // TODO support claims field if (delta < 0) { currency.settle(manager, holder, uint256(-delta), false); } else {