Skip to content

Commit

Permalink
feat: improve getAmountIn() function
Browse files Browse the repository at this point in the history
  • Loading branch information
bertmiller committed May 11, 2023
1 parent 6258205 commit 9aa1294
Show file tree
Hide file tree
Showing 13 changed files with 51,805 additions and 9,463 deletions.
851 changes: 427 additions & 424 deletions out/blindBackrun.t.sol/BlindBackrunTest.json

Large diffs are not rendered by default.

845 changes: 424 additions & 421 deletions out/blindBackrun.t.sol/IUniswapFactory.json

Large diffs are not rendered by default.

845 changes: 424 additions & 421 deletions out/blindBackrun.t.sol/IUniswapV2Router.json

Large diffs are not rendered by default.

10,015 changes: 7,225 additions & 2,790 deletions out/blindBackrunDebug.sol/BlindBackrun.json

Large diffs are not rendered by default.

14,107 changes: 14,107 additions & 0 deletions out/blindBackrunDebug.sol/IPairReserves.json

Large diffs are not rendered by default.

9,158 changes: 6,502 additions & 2,656 deletions out/blindBackrunDebug.sol/IUniswapV2Pair.json

Large diffs are not rendered by default.

9,158 changes: 6,502 additions & 2,656 deletions out/blindBackrunDebug.sol/IWETH.json

Large diffs are not rendered by default.

6,072 changes: 6,072 additions & 0 deletions out/blindBackrunMainnet.t.sol/BlindBackrunTest.json

Large diffs are not rendered by default.

4,870 changes: 4,870 additions & 0 deletions out/blindBackrunMainnet.t.sol/IUniswapFactory.json

Large diffs are not rendered by default.

4,999 changes: 4,999 additions & 0 deletions out/blindBackrunMainnet.t.sol/IUniswapV2Router.json

Large diffs are not rendered by default.

169 changes: 151 additions & 18 deletions src/blindBackrunDebug.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,19 @@ interface IUniswapV2Pair {
function token1() external view returns (address);
}

contract BlindBackrun is Ownable {
using SafeMath for uint256;

struct PairReserves {
interface IPairReserves{
struct PairReserves {
uint256 reserve0;
uint256 reserve1;
uint256 price;
bool isWETHZero;
}
}

contract BlindBackrun is Ownable {
using SafeMath for uint256;
uint256 uniswappyFee = 997;
uint256 uniswappyFeeSquared = uniswappyFeeSquared;

address public immutable WETH_ADDRESS;

Expand All @@ -49,14 +53,19 @@ contract BlindBackrun is Ownable {
IUniswapV2Pair firstPair = IUniswapV2Pair(firstPairAddress);
IUniswapV2Pair secondPair = IUniswapV2Pair(secondPairAddress);

PairReserves memory firstPairData = getPairData(firstPair);
PairReserves memory secondPairData = getPairData(secondPair);
console.log("\n--------- PAIR DATA ---------");

IPairReserves.PairReserves memory firstPairData = getPairData(firstPair);
IPairReserves.PairReserves memory secondPairData = getPairData(secondPair);

console.log("\n--------- PRICES ---------");
console.log("firstPair price : %s", firstPairData.price);
console.log("secondPair price : %s", secondPairData.price);

uint256 amountIn = getAmountIn(firstPairData, secondPairData);
console.log("\n--------- TRADE AMOUNTS ---------");
console.log("amountIn : %s", amountIn);

IERC20(WETH_ADDRESS).transfer(firstPairAddress, amountIn);

uint256 firstPairAmountOut;
Expand All @@ -65,8 +74,6 @@ contract BlindBackrun is Ownable {
firstPairAmountOut = getAmountOut(amountIn, firstPairData.reserve0, firstPairData.reserve1);
finalAmountOut = getAmountOut(firstPairAmountOut, secondPairData.reserve1, secondPairData.reserve0);

console.log("\n--------- TRADE AMOUNTS ---------");
console.log("amountIn : %s", amountIn);
console.log("firstPairAmountOut: %s", firstPairAmountOut);
console.log("finalAmountOut : %s", finalAmountOut);
console.log("arb profit : %s", (finalAmountOut.sub(amountIn)));
Expand Down Expand Up @@ -110,21 +117,147 @@ contract BlindBackrun is Ownable {
/// @param firstPairData Struct containing data about the first Uniswap V2 pair.
/// @param secondPairData Struct containing data about the second Uniswap V2 pair.
/// @return amountIn, the optimal amount to trade to arbitrage two v2 pairs.
function getAmountIn(PairReserves memory firstPairData, PairReserves memory secondPairData) internal pure returns (uint256) {
uint256 uniswappyFee = 997;
uint256 numerator = sqrt(uniswappyFee.mul(uniswappyFee).mul(firstPairData.price).mul(secondPairData.price)).sub(1e18);
uint256 denominatorPart1 = (uniswappyFee.mul(1e18)).div(firstPairData.reserve1);
uint256 denominatorPart2 = (uniswappyFee.mul(uniswappyFee).mul(firstPairData.price)).div(secondPairData.reserve1);
uint256 denominator = denominatorPart1.add(denominatorPart2);
uint256 amountIn = numerator.div(denominator);
function getAmountIn(
IPairReserves.PairReserves memory firstPairData,
IPairReserves.PairReserves memory secondPairData
) public returns (uint256) {
uint256 numerator = getNumerator(firstPairData, secondPairData);
uint256 denominator = getDenominator(firstPairData, secondPairData);

uint256 amountIn =
numerator
.mul(1000)
.div(denominator);

return amountIn;
}

function getNumerator(
IPairReserves.PairReserves memory firstPairData,
IPairReserves.PairReserves memory secondPairData
) public view returns (uint256) {
if (firstPairData.isWETHZero == true) {
uint presqrt =
uniswappyFee
.mul(uniswappyFee)
.mul(firstPairData.reserve1)
.mul(secondPairData.reserve0)
.div(secondPairData.reserve1)
.div(firstPairData.reserve0);

uint256 numerator =
(
sqrt(presqrt)
.sub(1e3)
)
.mul(secondPairData.reserve1)
.mul(firstPairData.reserve0);

return numerator;
} else {
uint presqrt =
uniswappyFee
.mul(uniswappyFee)
.mul(firstPairData.reserve0)
.mul(secondPairData.reserve1)
.div(secondPairData.reserve0)
.div(firstPairData.reserve1);

uint256 numerator =
(
sqrt(presqrt)
.sub(1e3)
)
.mul(secondPairData.reserve0)
.mul(firstPairData.reserve1);

return numerator;
}
}

function getDenominator(
IPairReserves.PairReserves memory firstPairData,
IPairReserves.PairReserves memory secondPairData
) public returns (uint256){
if (firstPairData.isWETHZero == true) {
uint256 denominator =
(
uniswappyFee
.mul(secondPairData.reserve1)
.mul(1000)
)
.add(
uniswappyFee
.mul(uniswappyFee)
.mul(firstPairData.reserve1)
);
return denominator;
} else {
uint256 denominator =
(
uniswappyFee
.mul(secondPairData.reserve0)
.mul(1000)
)
.add(
uniswappyFee
.mul(uniswappyFee)
.mul(firstPairData.reserve0)
);
return denominator;
}
}

function getFlippedFakePairData(bool first) external view returns (IPairReserves.PairReserves memory){
uint256 reserve0;
uint256 reserve1;
if (first){
reserve1 = 17221979511711;
reserve0 = 9022829950419911882261;
} else {
reserve1 = 24221870080988;
reserve0 = 29260889455340067009671;
}

uint256 price;

bool isWETHZero = true;

price = reserve0.mul(1e18).div(reserve1);

return IPairReserves.PairReserves(reserve0, reserve1, price, isWETHZero);
}


function getFakePairData(bool first) external view returns (IPairReserves.PairReserves memory){
uint256 reserve0;
uint256 reserve1;
if (first){
reserve0 = 17221979511711000000000;
reserve1 = 9022829950419911882261;
} else {
reserve0 = 24221870080988000000000;
reserve1 = 29260889455340067009671;
}

uint256 price;

bool isWETHZero = false;

price = reserve0.mul(1e18).div(reserve1);

return IPairReserves.PairReserves(reserve0, reserve1, price, isWETHZero);
}

/// @notice Retrieves price and reserve data for a given Uniswap V2 pair. Also checks which token is WETH.
/// @param pair The Uniswap V2 pair to retrieve data for.
/// @return A PairReserves struct containing price and reserve data for the given pair.
function getPairData(IUniswapV2Pair pair) private view returns (PairReserves memory) {
/// @return A IPairReserves.PairReserves struct containing price and reserve data for the given pair.
function getPairData(IUniswapV2Pair pair) private view returns (IPairReserves.PairReserves memory) {
(uint256 reserve0, uint256 reserve1, ) = pair.getReserves();
console.log("pair:", address(pair));
console.log("reserve0:",reserve0);
console.log("reserve1:", reserve1);

uint256 price;

bool isWETHZero = false;
Expand All @@ -135,7 +268,7 @@ contract BlindBackrun is Ownable {
price = reserve0.mul(1e18).div(reserve1);
}

return PairReserves(reserve0, reserve1, price, isWETHZero);
return IPairReserves.PairReserves(reserve0, reserve1, price, isWETHZero);
}

/// @notice Calculates the square root of a given number.
Expand Down
77 changes: 0 additions & 77 deletions test/blindBackrun.t.sol

This file was deleted.

Loading

0 comments on commit 9aa1294

Please sign in to comment.