Skip to content

Commit

Permalink
add getPoolState extsload
Browse files Browse the repository at this point in the history
  • Loading branch information
xyek committed May 31, 2024
1 parent 59915ac commit be6f9bf
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 3 deletions.
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
23 changes: 23 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,28 @@ library StateLibrary {
// index of Position.Info mapping in Pool.State: mapping(bytes32 => Position.Info) positions;
uint256 public constant POSITIONS_OFFSET = 6;

struct PoolStateView {
Slot0 slot0;
uint256 feeGrowthGlobal0X128;
uint256 feeGrowthGlobal1X128;
uint128 liquidity;
}

/**
* @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 state The state of the pool.
*/
function getPoolState(IPoolManager manager, PoolId poolId) internal view returns (PoolStateView memory state) {
bytes32 stateSlot = _getPoolStateSlot(poolId);
bytes memory data = manager.extsload(stateSlot, 4);
assembly {
state := add(data, 32)
}
}

/**
* @notice Get Slot0 of the pool: sqrtPriceX96, tick, protocolFee, lpFee
* @dev Corresponds to pools[poolId].slot0
Expand Down
36 changes: 33 additions & 3 deletions test/libraries/StateLibrary.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,36 @@ 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);

StateLibrary.PoolStateView memory state = StateLibrary.getPoolState(manager, poolId);
snapLastCall("extsload getPoolState");

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

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

(uint256 feeGrowthGlobal0, uint256 feeGrowthGlobal1) = StateLibrary.getFeeGrowthGlobals(manager, poolId);
assertEq(state.feeGrowthGlobal0X128, feeGrowthGlobal0);
assertEq(state.feeGrowthGlobal1X128, feeGrowthGlobal1);
}

function test_getSlot0() public {
// create liquidity
modifyLiquidityRouter.modifyLiquidity(
Expand All @@ -50,15 +80,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

0 comments on commit be6f9bf

Please sign in to comment.