1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use ;
use TickIndex;
/// Constants for pool state slots
pub const POOLS_SLOT: U256 = uint!;
pub const FEE_GROWTH_GLOBAL0_OFFSET: U256 = uint!;
pub const LIQUIDITY_OFFSET: U256 = uint!;
pub const TICKS_OFFSET: U256 = uint!;
pub const TICK_BITMAP_OFFSET: U256 = uint!;
pub const POSITIONS_OFFSET: U256 = uint!;
/// Get the storage slot for a pool's state structure
///
/// In Uniswap V4 contract, pools is a mapping(bytes32 => State) stored at slot
/// 6 (POOLS_SLOT).
///
/// The State struct storage layout:
/// ```
/// struct State {
/// Slot0 slot0; // state_slot + 0
/// uint256 feeGrowthGlobal0X128; // state_slot + 1
/// uint256 feeGrowthGlobal1X128; // state_slot + 2
/// uint128 liquidity; // state_slot + 3 (LIQUIDITY_OFFSET)
/// mapping(int24 => TickInfo) ticks; // mapping slot: state_slot + 4 (TICKS_OFFSET)
/// mapping(int16 => uint256) tickBitmap; // mapping slot: state_slot + 5 (TICK_BITMAP_OFFSET)
/// mapping(bytes32 => Position.State) positions; // mapping slot: state_slot + 6 (POSITIONS_OFFSET)
/// }
/// ```
///
/// For mapping-type fields, calculate the storage location for a key:
/// slot = keccak256(key, mapping_slot)
///
/// For regular fields, storage location is: state_slot + offset
///
/// ## Arguments
/// * `pool_id` - Unique identifier for the pool (B256)
///
/// ## Returns
/// The starting storage slot position of the State struct (state_slot)
/// Get the storage slot for a pool's liquidity value
///
/// liquidity is a uint128 field in the State struct, stored at state_slot + 3.
/// Note: Due to V4's special storage layout, keccak256 is used to calculate the
/// final location.
///
/// ## Arguments
/// * `pool_id` - Unique identifier for the pool
///
/// ## Returns
/// The storage slot location of the liquidity field
/// Get the storage slot for a specific tick in the tick bitmap
///
/// tickBitmap is a mapping(int16 wordPos => uint256) used for fast lookup of
/// words containing active ticks. Each word can represent 256 ticks (each bit
/// represents one tick).
///
/// ## Arguments
/// * `pool_id` - Unique identifier for the pool
/// * `tick` - Tick value, which will be converted to the corresponding word
/// position (int16)
///
/// ## Returns
/// The storage slot location of this word position in the tickBitmap mapping
/// Get the storage slot for a specific tick's information
///
/// ticks is a mapping(int24 => TickInfo) that stores detailed information for
/// each tick, including total liquidity, net liquidity, fee growth outside,
/// etc.
///
/// ## Arguments
/// * `pool_id` - Unique identifier for the pool
/// * `tick` - Tick value (int24)
///
/// ## Returns
/// The storage slot location of the TickInfo data for this tick in the ticks
/// mapping
/// Get the storage slot for a specific position's information
///
/// positions is a mapping(bytes32 positionKey => Position.State) that stores
/// state information for each liquidity position.
///
/// ## Arguments
/// * `pool_id` - Unique identifier for the pool
/// * `position_key` - Unique identifier for the position (typically
/// keccak256(owner, tickLower, tickUpper))
///
/// ## Returns
/// The storage slot location of the Position.State data for this position in
/// the positions mapping