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

add getPoolState method to the StateLibrary #721

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions .forge-snapshots/extsload getPoolState.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
973
26 changes: 26 additions & 0 deletions src/libraries/StateLibrary.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.21;

import {PoolId} from "../types/PoolId.sol";
import {Slot0} from "../types/Slot0.sol";
import {IPoolManager} from "../interfaces/IPoolManager.sol";
import {Currency} from "../types/Currency.sol";
import {Position} from "./Position.sol";
Expand Down Expand Up @@ -30,6 +31,31 @@ library StateLibrary {
// index of Position.Info mapping in Pool.State: mapping(bytes32 => Position.Info) positions;
uint256 public constant POSITIONS_OFFSET = 6;

/**
* @notice Get the global state of a pool.
* @dev Corresponds to pools[poolId]
* @param manager The pool manager contract.
* @param poolId The ID of the pool.
* @return slot0 The slot0 of the pool.
* @return feeGrowthGlobal0X128 The global fee growth for token0.
* @return feeGrowthGlobal1X128 The global fee growth for token1.
* @return liquidity The liquidity of the pool.
*/
function getPoolState(IPoolManager manager, PoolId poolId)
internal
view
returns (Slot0 slot0, uint256 feeGrowthGlobal0X128, uint256 feeGrowthGlobal1X128, uint128 liquidity)
{
bytes32 stateSlot = _getPoolStateSlot(poolId);
bytes memory data = manager.extsload(stateSlot, 4);
Copy link
Contributor

Choose a reason for hiding this comment

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

this needs to be updated to an array of bytes32 that gets returned

assembly {
slot0 := mload(add(data, 32))
feeGrowthGlobal0X128 := mload(add(data, 64))
feeGrowthGlobal1X128 := mload(add(data, 96))
liquidity := mload(add(data, 128))
Copy link
Contributor

Choose a reason for hiding this comment

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

needs to be masked to remove the other 128 bits of data from this data type

}
}

/**
* @notice Get Slot0 of the pool: sqrtPriceX96, tick, protocolFee, lpFee
* @dev Corresponds to pools[poolId].slot0
Expand Down
39 changes: 36 additions & 3 deletions test/libraries/StateLibrary.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {Hooks} from "../../src/libraries/Hooks.sol";
import {TickMath} from "../../src/libraries/TickMath.sol";
import {IPoolManager} from "../../src/interfaces/IPoolManager.sol";
import {PoolKey} from "../../src/types/PoolKey.sol";
import {Slot0} from "../../src/types/Slot0.sol";
import {BalanceDelta} from "../../src/types/BalanceDelta.sol";
import {PoolId, PoolIdLibrary} from "../../src/types/PoolId.sol";
import {CurrencyLibrary, Currency} from "../../src/types/Currency.sol";
Expand Down Expand Up @@ -37,6 +38,38 @@ contract StateLibraryTest is Test, Deployers, Fuzzers, GasSnapshot {
manager.initialize(key, SQRT_PRICE_1_1, ZERO_BYTES);
}

function test_getPoolState() public {
// create liquidity
modifyLiquidityRouter.modifyLiquidity(
key, IPoolManager.ModifyLiquidityParams(-60, 60, 10_000 ether, 0), ZERO_BYTES
);

modifyLiquidityRouter.modifyLiquidity(
key, IPoolManager.ModifyLiquidityParams(-600, 600, 10_000 ether, 0), ZERO_BYTES
);

// swap to create fees, crossing a tick
uint256 swapAmount = 100 ether;
swap(key, true, -int256(swapAmount), ZERO_BYTES);

(Slot0 slot0, uint256 feeGrowthGlobal0X128, uint256 feeGrowthGlobal1X128, uint128 liquidity) =
StateLibrary.getPoolState(manager, poolId);
snapLastCall("extsload getPoolState");

assertEq(slot0.sqrtPriceX96(), 78680104762184586858280382455);
Copy link
Contributor

Choose a reason for hiding this comment

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

can you instead test these against getSlot0?

assertEq(slot0.tick(), -139);
assertEq(slot0.protocolFee(), 0);
assertEq(slot0.lpFee(), 3000);

uint256 liquidityExpected = StateLibrary.getLiquidity(manager, poolId);
assertEq(liquidity, liquidityExpected);

(uint256 feeGrowthGlobal0Expected, uint256 feeGrowthGlobal1Expected) =
StateLibrary.getFeeGrowthGlobals(manager, poolId);
assertEq(feeGrowthGlobal0X128, feeGrowthGlobal0Expected);
assertEq(feeGrowthGlobal1X128, feeGrowthGlobal1Expected);
}

function test_getSlot0() public {
// create liquidity
modifyLiquidityRouter.modifyLiquidity(
Expand All @@ -50,15 +83,15 @@ contract StateLibraryTest is Test, Deployers, Fuzzers, GasSnapshot {
// swap to create fees, crossing a tick
uint256 swapAmount = 100 ether;
swap(key, true, -int256(swapAmount), ZERO_BYTES);
(uint160 sqrtPriceX96, int24 tick, uint24 protocolFee, uint24 swapFee) = StateLibrary.getSlot0(manager, poolId);

(uint160 sqrtPriceX96, int24 tick, uint24 protocolFee, uint24 lpFee) = StateLibrary.getSlot0(manager, poolId);
snapLastCall("extsload getSlot0");
assertEq(tick, -139);

// magic number verified against a native getter
assertEq(sqrtPriceX96, 78680104762184586858280382455);
assertEq(tick, -139);
assertEq(protocolFee, 0); // tested in protocol fee tests
assertEq(swapFee, 3000);
assertEq(lpFee, 3000);
}

function test_getTickLiquidity() public {
Expand Down