Skip to content

Commit

Permalink
feat: clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
ts0yu authored Sep 21, 2024
1 parent c7c00fd commit 0c08d8e
Show file tree
Hide file tree
Showing 10 changed files with 14 additions and 338 deletions.
105 changes: 1 addition & 104 deletions contracts/utils/src/ArenaController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ contract ArenaController {
require(currency0.approve(address(swapRouter), type(uint256).max), "Approval for currency0 failed");
require(currency1.approve(address(swapRouter), type(uint256).max), "Approval for currency1 failed");

(uint160 sqrtPriceX96, int24 tick,,) = fetcher.getSlot0(poolManager, fetcher.toId(poolKey));
(uint160 sqrtPriceX96,,,) = fetcher.getSlot0(poolManager, fetcher.toId(poolKey));

uint256 uniswapPrice = FullMath.mulDiv(uint256(sqrtPriceX96) * 10**18, uint256(sqrtPriceX96), 1 << 192);
uint256 lexPrice = lex.price();
Expand Down Expand Up @@ -161,107 +161,4 @@ 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,
uint128 liquidity,
int256 amountRemaining,
uint24 feePips
) external pure returns (uint160 sqrtPriceNextX96, uint256 amountIn, uint256 amountOut, uint256 feeAmount) {
unchecked {
uint256 _feePips = feePips; // upcast once and cache
bool zeroForOne = sqrtPriceCurrentX96 >= sqrtPriceTargetX96;
bool exactIn = amountRemaining < 0;

if (exactIn) {
uint256 amountRemainingLessFee =
FullMath.mulDiv(uint256(-amountRemaining), MAX_SWAP_FEE - _feePips, MAX_SWAP_FEE);
amountIn = zeroForOne
? SqrtPriceMath.getAmount0Delta(sqrtPriceTargetX96, sqrtPriceCurrentX96, liquidity, true)
: SqrtPriceMath.getAmount1Delta(sqrtPriceCurrentX96, sqrtPriceTargetX96, liquidity, true);
if (amountRemainingLessFee >= amountIn) {
// `amountIn` is capped by the target price
sqrtPriceNextX96 = sqrtPriceTargetX96;
feeAmount = _feePips == MAX_SWAP_FEE
? amountIn // amountIn is always 0 here, as amountRemainingLessFee == 0 and amountRemainingLessFee >= amountIn
: FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_SWAP_FEE - _feePips);
} else {
// exhaust the remaining amount
amountIn = amountRemainingLessFee;
sqrtPriceNextX96 = SqrtPriceMath.getNextSqrtPriceFromInput(
sqrtPriceCurrentX96, liquidity, amountRemainingLessFee, zeroForOne
);
// we didn't reach the target, so take the remainder of the maximum input as fee
feeAmount = uint256(-amountRemaining) - amountIn;
}
amountOut = zeroForOne
? SqrtPriceMath.getAmount1Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, false)
: SqrtPriceMath.getAmount0Delta(sqrtPriceCurrentX96, sqrtPriceNextX96, liquidity, false);
} else {
amountOut = zeroForOne
? SqrtPriceMath.getAmount1Delta(sqrtPriceTargetX96, sqrtPriceCurrentX96, liquidity, false)
: SqrtPriceMath.getAmount0Delta(sqrtPriceCurrentX96, sqrtPriceTargetX96, liquidity, false);
if (uint256(amountRemaining) >= amountOut) {
// `amountOut` is capped by the target price
sqrtPriceNextX96 = sqrtPriceTargetX96;
} else {
// cap the output amount to not exceed the remaining output amount
amountOut = uint256(amountRemaining);
sqrtPriceNextX96 =
SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtPriceCurrentX96, liquidity, amountOut, zeroForOne);
}
amountIn = zeroForOne
? SqrtPriceMath.getAmount0Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, true)
: SqrtPriceMath.getAmount1Delta(sqrtPriceCurrentX96, sqrtPriceNextX96, liquidity, true);
// `feePips` cannot be `MAX_SWAP_FEE` for exact out
feeAmount = FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_SWAP_FEE - _feePips);
}
}
}
}
2 changes: 1 addition & 1 deletion src/artifacts/ArenaController.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion src/artifacts/ArenaToken.json

This file was deleted.

1 change: 0 additions & 1 deletion src/artifacts/LiquidExchange.json

This file was deleted.

1 change: 0 additions & 1 deletion src/artifacts/PoolManager.json

This file was deleted.

1 change: 0 additions & 1 deletion src/artifacts/PoolModifyLiquidityTest.json

This file was deleted.

1 change: 0 additions & 1 deletion src/artifacts/PoolSwapTest.json

This file was deleted.

15 changes: 5 additions & 10 deletions src/engine/arbitrageur.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use async_trait::async_trait;

use super::*;
use crate::{
types::{controller::ArenaController, swap::PoolSwapTest},
types::controller::ArenaController,
AnvilProvider, Signal,
};

Expand All @@ -19,24 +19,19 @@ pub trait Arbitrageur {
/// Default implementation of an [`Arbitrageur`] that uses the closed-form optimal swap amount to determine the optimal arbitrage.
#[derive(Default)]
pub struct FixedArbitrageur {
swapper: Option<Address>,
/// The fixed amount to swap on each arbitrage opportunity.
pub depth: Signed<256, 4>,
}

#[async_trait]
impl Arbitrageur for FixedArbitrageur {
async fn init(&mut self, signal: &Signal, provider: AnvilProvider) {
let swapper = PoolSwapTest::deploy(provider.clone(), signal.manager)
.await
.unwrap();

self.swapper = Some(*swapper.address());
}
async fn init(&mut self, _signal: &Signal, _provider: AnvilProvider) {}

async fn arbitrage(&mut self, signal: &Signal, provider: AnvilProvider) {
let controller = ArenaController::new(signal.controller, provider.clone());

controller
.equalizePrice(Signed::try_from(100000).unwrap())
.equalizePrice(self.depth)
.nonce(
provider
.clone()
Expand Down
38 changes: 2 additions & 36 deletions src/engine/mod.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,19 @@
use alloy::{
primitives::{Address, Signed, Uint, I256},
primitives::{Address, Signed, I256},
providers::{Provider, WalletProvider},
};

use super::*;
use crate::{
error::ArenaError,
types::{controller::ArenaController, pool_manager::PoolManager::PoolKey},
types::controller::ArenaController,
};
/// Defines a trait for custom arbitrage strategies.
pub mod arbitrageur;

/// Defines a trait that allows custom strategy logging and telemetry.
pub mod inspector;

/// Type that allows the parameters of a Uniswap v4 pool to be set.
#[derive(Default, Debug, Clone)]
pub struct PoolParameters {
/// Pool fee.
pub fee: Uint<24, 1>,

/// Pool tick spacing.
pub tick_spacing: Signed<24, 1>,

/// Pool hooks.
pub hooks: Address,
}

impl From<PoolKey> for PoolParameters {
fn from(key: PoolKey) -> Self {
Self {
fee: key.fee,
tick_spacing: key.tickSpacing,
hooks: key.hooks,
}
}
}

impl PoolParameters {
/// Public constructor function to instantiate a new `PoolParameters` struct.
pub fn new(hooks: Address, tick_spacing: Signed<24, 1>, fee: Uint<24, 1>) -> Self {
Self {
fee,
tick_spacing,
hooks,
}
}
}

/// Abstraction to allow strategies to call state changing functions on the PoolManager without having to worry about callbacks.
#[derive(Debug, Clone)]
pub struct Engine {
Expand Down
Loading

0 comments on commit 0c08d8e

Please sign in to comment.