Incomplete prototype
Things WIP Format Work in progress Work in progres Work in progress Work in progress Work in progress Work in progress Work in progress Work in progress Work in progress Work in progress Work in progress Work in progress Work in progress Work in progress Work in progress
This commit is contained in:
commit
7a1e03ee7a
19 changed files with 7242 additions and 0 deletions
89
onchain/src/ArbitrageManager.sol
Normal file
89
onchain/src/ArbitrageManager.sol
Normal file
|
@ -0,0 +1,89 @@
|
|||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.28;
|
||||
|
||||
import {IUniswapV2Pair} from "./IUniswapV2Pair.sol";
|
||||
import {IERC20} from "./IERC20.sol";
|
||||
|
||||
contract ArbitrageManager {
|
||||
uint256 constant f = 997;
|
||||
|
||||
function sqrt(uint256 x)
|
||||
public
|
||||
pure
|
||||
returns (uint128)
|
||||
{
|
||||
if (x == 0) return 0;
|
||||
else{
|
||||
uint256 xx = x;
|
||||
uint256 r = 1;
|
||||
if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; }
|
||||
if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; }
|
||||
if (xx >= 0x100000000) { xx >>= 32; r <<= 16; }
|
||||
if (xx >= 0x10000) { xx >>= 16; r <<= 8; }
|
||||
if (xx >= 0x100) { xx >>= 8; r <<= 4; }
|
||||
if (xx >= 0x10) { xx >>= 4; r <<= 2; }
|
||||
if (xx >= 0x8) { r <<= 1; }
|
||||
r = (r + x / r) >> 1;
|
||||
r = (r + x / r) >> 1;
|
||||
r = (r + x / r) >> 1;
|
||||
r = (r + x / r) >> 1;
|
||||
r = (r + x / r) >> 1;
|
||||
r = (r + x / r) >> 1;
|
||||
r = (r + x / r) >> 1;
|
||||
uint256 r1 = x / r;
|
||||
return uint128 (r < r1 ? r : r1);
|
||||
}
|
||||
}
|
||||
|
||||
function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut)
|
||||
public
|
||||
pure
|
||||
returns (uint256 amountOut)
|
||||
{
|
||||
require(amountIn > 0, "UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT");
|
||||
require(reserveIn > 0 && reserveOut > 0, "UniswapV2Library: INSUFFICIENT_LIQUIDITY");
|
||||
uint256 amountInWithFee = amountIn * 997;
|
||||
uint256 numerator = amountInWithFee * reserveOut;
|
||||
uint256 denominator = reserveIn * 1000 + amountInWithFee;
|
||||
amountOut = numerator / denominator;
|
||||
}
|
||||
|
||||
function optimalIn(uint256 X_A, uint256 Y_A, uint256 X_B, uint256 Y_B)
|
||||
public
|
||||
pure
|
||||
returns(uint256)
|
||||
{
|
||||
uint256 k = f * X_B / 1000 + f ** 2 / 1000 * X_A / 1000;
|
||||
uint256 phi = sqrt(f * X_A) * sqrt(Y_B * X_B / 1000 * Y_A);
|
||||
uint256 psi = Y_A * X_B;
|
||||
|
||||
if (psi >= phi) return 0;
|
||||
else return (phi - psi) / k;
|
||||
}
|
||||
|
||||
function swap(address _pairA, address _pairB, uint256 amountIn, bool direction)
|
||||
external
|
||||
returns (uint256 amountOut)
|
||||
{
|
||||
IUniswapV2Pair pairA = IUniswapV2Pair(_pairA);
|
||||
IUniswapV2Pair pairB = IUniswapV2Pair(_pairB);
|
||||
|
||||
IERC20 tokenA = direction ? IERC20(pairA.token0()) : IERC20(pairA.token1());
|
||||
|
||||
// Transfer the input tokens from the sender to pairA
|
||||
tokenA.transferFrom(msg.sender, address(pairA), amountIn);
|
||||
|
||||
// Perform the first swap on pairA
|
||||
(uint256 reserve0A, uint256 reserve1A,) = pairA.getReserves();
|
||||
amountOut = getAmountOut(amountIn, direction ? reserve0A : reserve1A, direction ? reserve1A : reserve0A);
|
||||
pairA.swap(direction ? 0 : amountOut, direction ? amountOut : 0, address(pairB), new bytes(0));
|
||||
|
||||
// Perform the second swap on pairB
|
||||
(uint256 reserve0B, uint256 reserve1B,) = pairB.getReserves();
|
||||
amountOut = getAmountOut(amountOut, direction ? reserve1B : reserve0B, direction ? reserve0B : reserve1B);
|
||||
pairB.swap(direction ? amountOut : 0, direction ? 0 : amountOut, msg.sender, new bytes(0));
|
||||
|
||||
// Ensure that the arbitrage is profitable
|
||||
require(amountOut > amountIn, "Arbitrage not profitable");
|
||||
}
|
||||
}
|
17
onchain/src/IERC20.sol
Normal file
17
onchain/src/IERC20.sol
Normal file
|
@ -0,0 +1,17 @@
|
|||
pragma solidity ^0.8.28;
|
||||
|
||||
interface IERC20 {
|
||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
|
||||
function name() external view returns (string memory);
|
||||
function symbol() external view returns (string memory);
|
||||
function decimals() external view returns (uint8);
|
||||
function totalSupply() external view returns (uint256);
|
||||
function balanceOf(address owner) external view returns (uint256);
|
||||
function allowance(address owner, address spender) external view returns (uint256);
|
||||
|
||||
function approve(address spender, uint256 value) external returns (bool);
|
||||
function transfer(address to, uint256 value) external returns (bool);
|
||||
function transferFrom(address from, address to, uint256 value) external returns (bool);
|
||||
}
|
53
onchain/src/IUniswapV2Pair.sol
Normal file
53
onchain/src/IUniswapV2Pair.sol
Normal file
|
@ -0,0 +1,53 @@
|
|||
pragma solidity ^0.8.28;
|
||||
|
||||
interface IUniswapV2Pair {
|
||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
|
||||
function name() external pure returns (string memory);
|
||||
function symbol() external pure returns (string memory);
|
||||
function decimals() external pure returns (uint8);
|
||||
function totalSupply() external view returns (uint256);
|
||||
function balanceOf(address owner) external view returns (uint256);
|
||||
function allowance(address owner, address spender) external view returns (uint256);
|
||||
|
||||
function approve(address spender, uint256 value) external returns (bool);
|
||||
function transfer(address to, uint256 value) external returns (bool);
|
||||
function transferFrom(address from, address to, uint256 value) external returns (bool);
|
||||
|
||||
function DOMAIN_SEPARATOR() external view returns (bytes32);
|
||||
function PERMIT_TYPEHASH() external pure returns (bytes32);
|
||||
function nonces(address owner) external view returns (uint256);
|
||||
|
||||
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
|
||||
external;
|
||||
|
||||
event Mint(address indexed sender, uint256 amount0, uint256 amount1);
|
||||
event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
|
||||
event Swap(
|
||||
address indexed sender,
|
||||
uint256 amount0In,
|
||||
uint256 amount1In,
|
||||
uint256 amount0Out,
|
||||
uint256 amount1Out,
|
||||
address indexed to
|
||||
);
|
||||
event Sync(uint112 reserve0, uint112 reserve1);
|
||||
|
||||
function MINIMUM_LIQUIDITY() external pure returns (uint256);
|
||||
function factory() external view returns (address);
|
||||
function token0() external view returns (address);
|
||||
function token1() external view returns (address);
|
||||
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
|
||||
function price0CumulativeLast() external view returns (uint256);
|
||||
function price1CumulativeLast() external view returns (uint256);
|
||||
function kLast() external view returns (uint256);
|
||||
|
||||
function mint(address to) external returns (uint256 liquidity);
|
||||
function burn(address to) external returns (uint256 amount0, uint256 amount1);
|
||||
function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;
|
||||
function skim(address to) external;
|
||||
function sync() external;
|
||||
|
||||
function initialize(address, address) external;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue