Skip to content

Commit

Permalink
feat: wip fee tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
ts0yu authored Sep 18, 2024
1 parent a980fc4 commit cd00e4d
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 4 deletions.
55 changes: 55 additions & 0 deletions contracts/utils/src/ArenaController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import {FullMath} from "v4-core/libraries/FullMath.sol";
import {SqrtPriceMath} from "v4-core/libraries/SqrtPriceMath.sol";
import {PoolSwapTest} from "v4-core/test/PoolSwapTest.sol";
import {TickMath} from "v4-core/libraries/TickMath.sol";
import {PoolId} from "v4-core/types/PoolId.sol";
import {IPoolManager} from "v4-core/interfaces/IPoolManager.sol";
import {Position} from "v4-core/libraries/Position.sol";

contract ArenaController {
PoolManager immutable poolManager;
Expand All @@ -31,6 +34,9 @@ contract ArenaController {
uint160 public constant MIN_PRICE_LIMIT = TickMath.MIN_SQRT_PRICE + 1;
uint160 public constant MAX_PRICE_LIMIT = TickMath.MAX_SQRT_PRICE - 1;

bytes32 public constant POOLS_SLOT = bytes32(uint256(6));
uint256 public constant POSITIONS_OFFSET = 6;

struct Signal {
int24 currentTick;
uint160 sqrtPriceX96;
Expand Down Expand Up @@ -59,6 +65,10 @@ contract ArenaController {
require(currency1.mint(address(this), 100000000000000), "Minting currency1 to liquid exchange failed");
}

function getRouter() external view returns (address) {
return address(router);
}

function constructSignal() public view returns (Signal memory) {
(uint160 sqrtPriceX96, int24 tick,,) = fetcher.getSlot0(poolManager, fetcher.toId(poolKey));

Expand Down Expand Up @@ -151,6 +161,51 @@ contract ArenaController {
router.modifyLiquidity(poolKey, params, "");
}

function getPositionInfo(
address owner,
int24 tickLower,
int24 tickUpper,
bytes32 salt
) external view returns (uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128) {
PoolId poolId = fetcher.toId(poolKey);
// positionKey = keccak256(abi.encodePacked(owner, tickLower, tickUpper, salt))
bytes32 positionKey = Position.calculatePositionKey(owner, tickLower, tickUpper, salt);

(liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128) = getPositionInfo(poolManager, poolId, positionKey);
}

function getPositionInfo(IPoolManager manager, PoolId poolId, bytes32 positionId)
internal
view
returns (uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128)
{
bytes32 slot = _getPositionInfoSlot(poolId, positionId);

// read all 3 words of the Position.State struct
bytes32[] memory data = manager.extsload(slot, 3);

assembly ("memory-safe") {
liquidity := mload(add(data, 32))
feeGrowthInside0LastX128 := mload(add(data, 64))
feeGrowthInside1LastX128 := mload(add(data, 96))
}
}

function _getPositionInfoSlot(PoolId poolId, bytes32 positionId) internal pure returns (bytes32) {
// slot key of Pool.State value: `pools[poolId]`
bytes32 stateSlot = _getPoolStateSlot(poolId);

// Pool.State: `mapping(bytes32 => Position.State) positions;`
bytes32 positionMapping = bytes32(uint256(stateSlot) + POSITIONS_OFFSET);

// slot of the mapping key: `pools[poolId].positions[positionId]
return keccak256(abi.encodePacked(positionId, positionMapping));
}

function _getPoolStateSlot(PoolId poolId) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(PoolId.unwrap(poolId), POOLS_SLOT));
}

function computeSwapStep(
uint160 sqrtPriceCurrentX96,
uint160 sqrtPriceTargetX96,
Expand Down
2 changes: 1 addition & 1 deletion src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<V> Arena<V> {

controller
.setPool(
Uint::from(0),
Uint::from(10000),
Signed::try_from(2).unwrap(),
Address::default(),
Uint::from(24028916059024274524587271040_u128),
Expand Down
2 changes: 1 addition & 1 deletion src/artifacts/ArenaController.json

Large diffs are not rendered by default.

20 changes: 18 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ mod tests {
feed::OrnsteinUhlenbeck,
strategy::Strategy,
};
use alloy::providers::WalletProvider;
use crate::types::controller::ArenaController;
use alloy::primitives::FixedBytes;

struct StrategyMock;

Expand All @@ -349,12 +352,25 @@ mod tests {
}
async fn process(
&self,
_provider: AnvilProvider,
provider: AnvilProvider,
signal: Signal,
_inspector: &mut Box<dyn Inspector<T>>,
_engine: Engine,
) {
println!("signal: {:?}", signal);
let controller = ArenaController::new(signal.controller, provider.clone());

let position_info = controller
.getPositionInfo(
controller.getRouter().call().await.unwrap()._0,
Signed::try_from(-1000).unwrap(),
Signed::try_from(1000).unwrap(),
FixedBytes::ZERO,
)
.call()
.await
.unwrap();

println!("position_info: {:?}", position_info);
}
}

Expand Down

0 comments on commit cd00e4d

Please sign in to comment.