The amount to be borrowed when calling UniSwap
Calculate the prices of trading pairs in the OneSwap and UniSwap fund pools respectively.
oneSwapReceived: ,costs will exceed returns when all the price spread is filled,oneReserves) console.log(calculate profit,placed in order,the order book data can be put into consideration as well;one trading pair (such as ETH/USDT) may have two markets,the deposit amount for UniSwap: the deposited fund with index=0 of token0 and the deposited fund with index=1 of token1;which will lower the rate of return.The first step in calculating the price is to unify the order of the deposit amount for the two fund pools;each fund pool has two corresponding token deposit amounts to provide traders with liquidity;For arbitrage of other trading pairs,see:;one with the limit order function and the other without it;uniReserves) else uniRequired = getAmountInUniSwap(amountAndInputToken.amount,oneSwapReceived.toString(),reserves] async function queryOneSwapReserve(pairAddr) console.log(oneswap pair : + pairAddr);in the format of[uniswapToken0,…. In UniSwap-like decentralized exchanges?
$ P_1 = (M + \Delta m) / (S – \Delta s) = K / (S – \Delta s)2= (M + \ \Delta m)2/ K $
uniSwapPrice oneSwapPrice, then borrow the money token from UniSwap, and buy the stock token in the OneSwap market. Raise the price to the same level as in UniSwap, and calculate the amount to be borrowed
This function involves two formulas, and the derivation process is as follows:
flashSwap: Simply put, a user borrows a certain token from UniSwaps trading pair pool and calls the pre-deployed arbitrage contract for the risk-free arbitrage with the fund pool of other decentralized exchanges. After that, the borrowed assets of equivalent value are refunded. In this risk-free arbitrage, users only need to pay transaction fees on Ethereum, and do not need to hold any tokens.
the sample code is as follows:The return value of the above function is(amount(Big),oneReserves) else oneSwapReceived = getAmountOutOneSwap(amountAndInputToken.amount,at this time,tokens) let uniRequired;calculate the amount of funds needed to fill the price spread between the two fund pools.borrowToken: the address of the borrowed tokensThe number of tokens that need to be refunded to UniSwapNext,for more details,uniReserves,to query the deposited funds in the two trading pair contracts,The $100 here is derived from the comprehensive consideration of the transaction fee of Ethereum during this period + the time when the transaction gets on the chain (because there may be users on the chain during this period to reduce the price spread).key indicates the address of the fund pool and the name of the trading pair on the two exchanges,and it needs to be in the same order as the addresses of the pair in UniSwap and OneSwap // eth/usdt.
oneswapStock,risk-free arbitrage can be implemented in various decentralized exchanges.Adjust the order of the deposit amount of UniSwap to be consistent with that of OneSwap;just add more tokens to the configuration.Based on the calculated price,and arbitrage can continue. The disadvantage is such that the arbitrage,return [reserves,0xdAC17F958D2ee523a97C13D831ec7]);write the result directly here: $ \Delta s = \sqrtS * M / P_1-S $The ordering rules for tokens that make up the trading pair in UniSwap: tokens with a small address come first. The sorting rules for tokens that make up the trading pair in OneSwap: stock token first,0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2,// Borrow money for stock arbitrage,if there happens to be an order book that can be traded in OneSwap,it is necessary to send arbitrage transactions only when the profit is high enough (for example: 100 USDT).Similar to the above derivation,there is still room for arbitrage in the next query,the greater the slippage. As a result,
In a UniSwap-like decentralized exchange, each fund pool is composed of a trading pair (that is, containing two kinds of tokens), so the first step is to configure a fund pool for arbitrage. Considering the difference in the sorting algorithms of the two tokens that make up the trading pair contract on different exchanges, in this step, you need to manually set the order of the two trading tokens (to facilitate the price calculation in the next step)
uniReserves,yet the advantage is that the offline calculation and data query become less complex.By assembling the above functions,oneSwapReceived: oneSwapReceived Query the data of fund pools on different exchangesThat is,let pairContract = await oneswapPairContract.at(pairAddr);uniReserves,which means that there is no arbitrage opportunity and you can exit directly.Calculate the price of the fund pool on different exchangesIn the calculation,oneSwapPairAddr pairs.set(0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852;and increase the price in the OneSwap market if (uniPrice onePrice) if (uniPrice onePrice * 1.03) return amount: -2 uniPrice = onePrice * 1.03 amount = Big(oneReserves).times(Big(oneReserves)).times(Big(uniPrice)).sqrt().minus(Big(oneReserves)) borrowToken = tokens // Borrow money …… console.log(calculate amount end: ,separated by.
and calculate the amount to be borrowedvalue indicates the tokens that make up the fund pool on the two exchanges,therefore,let oneSwapReceived;oneReserves,which mainly includes the following functions:unction calReceivedAndRequiredAmount(amountAndBorrowToken!
So far, the first version of the MVP of an arbitrage robot has been completed, and most of the core functions have already been made available. However, during arbitrage on decentralized exchanges of Ethereum, there is another essential element in addition to the arbitrage program: the Ethereum node the arbitrage program connects to, preferably is the mining pool. This can ensure that transactions are on the chain in time, thus guaranteeing the success rate of arbitrage transactions.
An arbitrage contract requires two parameters: first, whether the token0 of UniSwap is the stock token of OneSwap. Just pass it in according to the configuration. Second, the market address of OneSwap.
function resortUniReserves(tokens, uniReserves) if (tokens === tokens) // uniToken0 == stock return uniReserves else if (tokens === tokens) uniToken0 == money return [uniReserves, uniReserves]
The return value of this function isthe amount obtained from the two fund pools/the amount required;
Price calculation formula:price = money / stock;
Since the algorithm of the trading engine varies among different decentralized exchanges, it is necessary to write specific arbitrage contracts for various exchanges.
There is a hard-coded value in the calculation:1.03, which is arbitrarily set and has not been tested by actual data;
oneReserves,let reserves = await pairContract.getReserves();you can send an arbitrage transaction and call UniSwaps flash swap (flash loan) for profit.The second step is to calculate the number of Token B obtained when inputting some Token A in OneSwap. The sample code is as follows:we can get a running robot.Therefore,amount.toString()) return amount:amount,which is supposed to be completed by only one transaction,0xdAC17F958D2ee523a97C13D831ec7,let borrowToken;followed by the money token;function tillUniSwapPriceNeededAmount(uniReserves,with the function of flashSwap provided by UniSwap,in the format ofuniSwapPairAddr;the returned amount array is the amount with index=0 ofstock tokenand the amount with index=1 ofmoney token.Parameters required for an arbitrage contract:Example of UniSwap and OneSwap arbitrage contracts:$ (M + \Delta m) * (S – \Delta s) = K = M * S $But in this case,oneSwapPairAddr;and it may take a while for the transaction to be on the chain (especially in the congestion of Ethereum)Borrow the stock token and sell the stock token to lower the price of the OneSwap fund pool.After all the above calculations,;ETH/USDT,reserves] Can the transaction fee be covered by the tokens gained?Here,PairSymbolNote: The order book function in the OneSwap market complicates the data query and calculation in calculating the arbitrage space;// Step 1: Calculate the number of tokens that need to be refunded to UniSwap if (amountAndBorrowToken.borrowToken === tokens) uniRequired = getAmountInUniSwap(amountAndInputToken.amount.
async function loop() initPairs() console.log(enter loop) while (true) console.log(enter …) await work() async function work() console.log(work …: ) for (let pair of pairs) let pairAddrs = spiltPairs(pair) console.log(\n\n\ncheck pair: , pairAddrs) let uniReserves = await queryUniSwapReserve(pairAddrs); // toke1, token2 let oneReserves = await queryOneSwapReserve(pairAddrs); // stock, money let tokenAndAmount = hasChanceToArbitrage(pair, uniReserves, oneReserves) console.log(calculate profit amount: , tokenAndAmount.profit, ; input token amount: , tokenAndAmount.amount) if (tokenAndAmount.amount 0) await sendTx(tokenAndAmount, pairAddrs, pair)
async function sendTx(tokenAndAmount, uniSwapPairAddr, tokens) let bytes = web3.eth.abi.encodeParameters([bool,bool],[tokenAndAmount.uniSwapToken0IsStock, false]); let contract = await uniswapPairContract.at(uniSwapPairAddr); if putToken === tokens) await contract.swap(tokenAndAmount.amount, 0, arbitrageAddr, bytes); else if ((tokenAndAmount.inputToken === tokens) ) await contract.swap(0, tokenAndAmount.amount, arbitrageAddr, bytes);
If token0 is borrowed, write its quantity in the first parameter, and vice versa.
Borrow the money token and buy the stock token to increase the price of the OneSwap fund pool.
Calculate the number of tokens that need to be borrowed from UniSwap to fill the spread between the fund pools
The author believes that the success of arbitrage depends on the above two factors: the performance of the arbitrage program and the connected Ethereum node; both are indispensable. The arbitrage program can ensure the arbitrage opportunities on decentralized exchanges; the connected nodes can guarantee the realization of such opportunities. The article below elaborates on the importance of nodes for arbitrage on Ethereum.
1.03 indicates arbitraging only 3% of the price of the current OneSwap trading pair
Note: Assuming that a user borrows Token A from UniSwap, then he needs to refund Token B in the equivalent value (price*amount);
The deposit amount for OneSwap: the deposited fund with index=0 of stock and the deposited fund with index=1 of money;
Here, we did not introduce the profit amount but use only the profit slippage. We need to further optimize it by introducing the profit amount for control. That is because under normal circumstances, the unit price of each token will not change much in one day; therefore, you can write the price of the token of the day in the configuration to calculate profit.
uniSwapPairAddr;may require multiple transactions;calculate the number of tokens that need to be refunded to UniSwap.amount: the number of tokens borrowed from UniSwapIndex 1: The amount obtained from the OneSwap fund poolAccording to the formula:price = moneyTokenAmount / stockTokenAmountuniSwapPrice oneSwapPrice,uniRequired: ,the price of the fund pool cannot be increased/decreased to the same level as in UniSwap. Under this circumstance,oneswapMoney]The profit here is calculated off-chain,tokens) let uniPrice = calPrice(uniReserves) let onePrice = calPrice(oneReserves) let amount;oneReserves.
Based on the numbers of the two markets worked out in the previous step, calculate the profitable quantity; at the same time, two factors need to be considered here:
return [reserves,false means the limit order function is enabled.The prices are the same or almost the same (you can set the price slippage by yourself),Note: The deposit amount queried here is the same as the token sequence configured in the fund pool in the first step.In OneSwap,if there is an arbitrage opportunity,the derivation of two formulas is involved when the price range is filled:async function queryUniSwapReserve(pairAddr) console.log(uniswap pair : + pairAddr);function initPairs() pairs = new Map();borrowToken: borrowToken,the smaller the deposit amount of the fund pool,// note: The value here is the address of tokens.
Index 0: The amount required by the UniSwap fund pool
pair is a Map, key is a string, and value is an array
oneReserves,only the amount of theAMMdeposit is considered here;let pairContract = await uniswapPairContract.at(pairAddr);and sell the stock token in the OneSwap market. Lower the price to the same level as in UniSwap,borrowToken(string));then borrow the stock token from UniSwap.
0xD5c97DaA0bfF751e4282BbC5AC8D4;uniswapToken1,let reserves = await pairContract.getReserves();Two decentralized exchanges are used in the project:UniSwapandOneSwap;The robot described in this article is a simple MVP (Minimum Viable Product) version,because for every arbitrage,the slippage varies a lot on the price curve of different pools;here it is based on the order of OneSwap;uniRequired.toString()) return uniRequired: uniRequired,uniReserves) // Step 2: Calculate the number of tokens obtained from OneSwap if (amountAndInputToken.borrowToken === tokens) oneSwapReceived = getAmountOutOneSwap(amountAndInputToken.amount,This value must be set because the amounts of deposited funds in the two decentralized exchanges differ greatly. For the same price range,[0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2.
Calculate the number of tokens that need to be refunded to UniSwap and the number of tokens that can be obtained from another exchange
// Exit when the profit is negligible if (oneSwapReceived uniRequired.times(slippage)) console.log(oneSwapReceived: , oneSwapReceived.toString(), ; uniRequired * slippage : , uniRequired.times(slippage).toString()) return input: -1