Skip to content

Commit

Permalink
feat: working fixed arbitrageur
Browse files Browse the repository at this point in the history
  • Loading branch information
ts0yu authored Sep 20, 2024
1 parent cd00e4d commit c7c00fd
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 34 deletions.
17 changes: 9 additions & 8 deletions contracts/utils/src/ArenaController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ contract ArenaController {

lex = new LiquidExchange(address(currency0), address(currency1), initialPrice);

require(currency0.mint(address(this), 100000000000000), "Minting currency0 to liquid exchange failed");
require(currency1.mint(address(this), 100000000000000), "Minting currency1 to liquid exchange failed");
require(currency0.mint(address(this), 10000000000000000000), "Minting currency0 to liquid exchange failed");
require(currency1.mint(address(this), 10000000000000000000), "Minting currency1 to liquid exchange failed");
}

function getRouter() external view returns (address) {
Expand Down Expand Up @@ -90,34 +90,35 @@ contract ArenaController {
lex.swap(tokenIn, amountIn);
}

function equalizePrice() public {
function equalizePrice(int256 depth) public {
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));

uint256 uniswapPrice = FullMath.mulDiv(sqrtPriceX96, sqrtPriceX96, 1 << 192) * 1e18;
uint256 uniswapPrice = FullMath.mulDiv(uint256(sqrtPriceX96) * 10**18, uint256(sqrtPriceX96), 1 << 192);
uint256 lexPrice = lex.price();

if (uniswapPrice > lexPrice) {
bool zeroForOne = true;

IPoolManager.SwapParams memory params = IPoolManager.SwapParams({
zeroForOne: zeroForOne,
amountSpecified: 1000000,
amountSpecified: depth,
sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT // unlimited impact
});

PoolSwapTest.TestSettings memory testSettings =
PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false});

swapRouter.swap(poolKey, params, testSettings, "");

} else if (uniswapPrice < lexPrice) {
bool zeroForOne = false;

IPoolManager.SwapParams memory params = IPoolManager.SwapParams({
zeroForOne: zeroForOne,
amountSpecified: 10000,
amountSpecified: depth,
sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT // unlimited impact
});

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

function getPositionInfo(
/*function getPositionInfo(
address owner,
int24 tickLower,
int24 tickUpper,
Expand Down Expand Up @@ -204,7 +205,7 @@ contract ArenaController {
function _getPoolStateSlot(PoolId poolId) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(PoolId.unwrap(poolId), POOLS_SLOT));
}
}*/

function computeSwapStep(
uint160 sqrtPriceCurrentX96,
Expand Down
19 changes: 17 additions & 2 deletions src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::{
strategy::Strategy,
types::controller::ArenaController,
};

/// Represents an [`Arena`] that can be used to run a simulation and execute strategies.
pub struct Arena<V> {
/// The underlying Anvil execution environment.
Expand Down Expand Up @@ -46,10 +47,10 @@ impl<V> Arena<V> {

controller
.setPool(
Uint::from(10000),
Uint::from(0),
Signed::try_from(2).unwrap(),
Address::default(),
Uint::from(24028916059024274524587271040_u128),
Uint::from(79228162514264337593543950336_u128),
Bytes::new(),
)
.send()
Expand Down Expand Up @@ -125,6 +126,20 @@ impl<V> Arena<V> {
.await
.map_err(|e| ArenaError::PendingTransactionError(e))?;

let signal = controller.constructSignal().call().await?._0;

let signal = Signal::new(
signal.lexPrice,
None,
signal.currentTick,
signal.sqrtPriceX96,
signal.manager,
signal.pool,
signal.fetcher,
self.feed.current_value(),
*controller.address(),
);

self.arbitrageur
.arbitrage(&signal, admin_provider.clone())
.await;
Expand Down
2 changes: 1 addition & 1 deletion src/artifacts/ArenaController.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/engine/arbitrageur.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl Arbitrageur for FixedArbitrageur {
let controller = ArenaController::new(signal.controller, provider.clone());

controller
.equalizePrice()
.equalizePrice(Signed::try_from(100000).unwrap())
.nonce(
provider
.clone()
Expand All @@ -50,6 +50,8 @@ impl Arbitrageur for FixedArbitrageur {
.watch()
.await
.unwrap();

println!("current: {}", signal.current_value);
}
}

Expand Down
41 changes: 19 additions & 22 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,12 @@ impl Signal {

#[cfg(test)]
mod tests {
use alloy::primitives::{Signed, Uint, I256};
use alloy::{
primitives::{FixedBytes, Signed, Uint, I256},
providers::WalletProvider,
};
use async_trait::async_trait;
use rug::{ops::Pow, Float};

use super::*;
use crate::{
Expand All @@ -324,10 +328,8 @@ mod tests {
},
feed::OrnsteinUhlenbeck,
strategy::Strategy,
types::controller::ArenaController,
};
use alloy::providers::WalletProvider;
use crate::types::controller::ArenaController;
use alloy::primitives::FixedBytes;

struct StrategyMock;

Expand All @@ -343,8 +345,8 @@ mod tests {
engine
.modify_liquidity(
I256::try_from(10000000).unwrap(),
Signed::try_from(-1000).unwrap(),
Signed::try_from(1000).unwrap(),
Signed::try_from(-887272).unwrap(),
Signed::try_from(887272).unwrap(),
provider,
)
.await
Expand All @@ -357,20 +359,12 @@ mod tests {
_inspector: &mut Box<dyn Inspector<T>>,
_engine: Engine,
) {
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();
let sqrt_price_x96 =
Float::with_val(53, Float::parse(signal.sqrt_price_x96.to_string()).unwrap());
let q96 = Float::with_val(53, 2).pow(96);
let price = Float::with_val(53, sqrt_price_x96 / q96).pow(2);

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

Expand All @@ -379,12 +373,15 @@ mod tests {
let builder: ArenaBuilder<_> = ArenaBuilder::new();

let mut arena: Arena<_> = builder
.with_strategy(Box::new(StrategyMock {}))
.with_feed(Box::new(OrnsteinUhlenbeck::new(10.0, 0.1, 0.1, 0.1, 0.1)))
.with_strategy(Box::new(StrategyMock))
.with_feed(Box::new(OrnsteinUhlenbeck::new(1.0, 0.1, 1.0, 0.1, 0.1)))
.with_inspector(Box::new(EmptyInspector {}))
.with_arbitrageur(Box::new(FixedArbitrageur::default()))
.build();

arena.run(Config::new(Uint::from(5000), 10)).await.unwrap();
arena
.run(Config::new(Uint::from(5000), 10000))
.await
.unwrap();
}
}

0 comments on commit c7c00fd

Please sign in to comment.