/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ import * as assert from 'assert'; import { Contract } from 'web3-eth-contract'; import { DODOContext, getDODOContext } from './utils/Context'; import { newContract, UNISWAP_ARBITRAGEUR_CONTRACT_NAME, UNISWAP_CONTRACT_NAME, } from './utils/Contracts'; import { decimalStr } from './utils/Converter'; import { logGas } from './utils/Log'; let lp: string; let keeper: string; let Uniswap: Contract; let UniswapArbitrageur: Contract; let UniswapReverse: Contract; let UniswapArbitrageurReverse: Contract; async function init(ctx: DODOContext): Promise { await ctx.setOraclePrice(decimalStr("100")); lp = ctx.spareAccounts[0]; keeper = ctx.spareAccounts[1]; await ctx.approveDODO(lp); await ctx.mintTestToken(lp, decimalStr("100"), decimalStr("10000")); await ctx.DODO.methods.depositBase(decimalStr("10")).send(ctx.sendParam(lp)); await ctx.DODO.methods .depositQuote(decimalStr("1000")) .send(ctx.sendParam(lp)); Uniswap = await newContract(UNISWAP_CONTRACT_NAME); Uniswap.methods .initialize(ctx.BASE.options.address, ctx.QUOTE.options.address) .send(ctx.sendParam(ctx.Deployer)); ctx.BASE.methods .transfer(Uniswap.options.address, decimalStr("10")) .send(ctx.sendParam(lp)); ctx.QUOTE.methods .transfer(Uniswap.options.address, decimalStr("2000")) .send(ctx.sendParam(lp)); Uniswap.methods.sync().send(ctx.sendParam(lp)); UniswapArbitrageur = await newContract(UNISWAP_ARBITRAGEUR_CONTRACT_NAME, [ Uniswap.options.address, ctx.DODO.options.address, ]); UniswapReverse = await newContract(UNISWAP_CONTRACT_NAME); UniswapReverse.methods .initialize(ctx.BASE.options.address, ctx.QUOTE.options.address) .send(ctx.sendParam(ctx.Deployer)); ctx.BASE.methods .transfer(UniswapReverse.options.address, decimalStr("10")) .send(ctx.sendParam(lp)); ctx.QUOTE.methods .transfer(UniswapReverse.options.address, decimalStr("2000")) .send(ctx.sendParam(lp)); UniswapReverse.methods.sync().send(ctx.sendParam(lp)); UniswapArbitrageurReverse = await newContract( UNISWAP_ARBITRAGEUR_CONTRACT_NAME, [UniswapReverse.options.address, ctx.DODO.options.address] ); } describe("Uniswap Arbitrageur", () => { let snapshotId: string; let ctx: DODOContext; before(async () => { ctx = await getDODOContext(); await init(ctx); }); beforeEach(async () => { snapshotId = await ctx.EVM.snapshot(); }); afterEach(async () => { await ctx.EVM.reset(snapshotId); }); describe("arbitrage with not reverse pair", () => { it("buy at dodo", async () => { await ctx.setOraclePrice(decimalStr("100")); // dodo price 100 uniswap price 200 // buy at dodo <<<<<<< Updated upstream await logGas( UniswapArbitrageur.methods.executeBuyArbitrage(decimalStr("1")), ctx.sendParam(keeper), "arbitrage buy at dodo not reverse" ); assert.equal( await ctx.QUOTE.methods.balanceOf(keeper).call(), "79836384956601695518" ); }); ======= logGas(await UniswapArbitrageur.methods.executeBuyArbitrage(decimalStr("1")), ctx.sendParam(keeper), "arbitrage buy at dodo not reverse") assert.equal(await ctx.QUOTE.methods.balanceOf(keeper).call(), "79836384956601695518") }) >>>>>>> Stashed changes it("sell at dodo", async () => { await ctx.setOraclePrice(decimalStr("300")); // dodo price 300 uniswap price 200 // sell at dodo <<<<<<< Updated upstream await logGas( UniswapArbitrageur.methods.executeSellArbitrage(decimalStr("1")), ctx.sendParam(keeper), "arbitrage sell at dodo not reverse" ); assert.equal( await ctx.BASE.methods.balanceOf(keeper).call(), "252761069524143743" ); }); }); ======= logGas(await UniswapArbitrageur.methods.executeSellArbitrage(decimalStr("1")), ctx.sendParam(keeper), "arbitrage sell at dodo not reverse") assert.equal(await ctx.BASE.methods.balanceOf(keeper).call(), "252761069524143743") }) }) >>>>>>> Stashed changes describe("arbitrage with reverse pair", () => { it("buy at dodo", async () => { await ctx.setOraclePrice(decimalStr("100")); // dodo price 100 uniswap price 200 // buy at dodo <<<<<<< Updated upstream await logGas( UniswapArbitrageurReverse.methods.executeBuyArbitrage(decimalStr("1")), ctx.sendParam(keeper), "arbitrage buy at dodo reverse" ); assert.equal( await ctx.QUOTE.methods.balanceOf(keeper).call(), "79836384956601695518" ); }); ======= logGas(await UniswapArbitrageurReverse.methods.executeBuyArbitrage(decimalStr("1")), ctx.sendParam(keeper), "arbitrage buy at dodo reverse") assert.equal(await ctx.QUOTE.methods.balanceOf(keeper).call(), "79836384956601695518") }) >>>>>>> Stashed changes it("sell at dodo", async () => { await ctx.setOraclePrice(decimalStr("300")); // dodo price 300 uniswap price 200 // sell at dodo <<<<<<< Updated upstream await logGas( UniswapArbitrageurReverse.methods.executeSellArbitrage(decimalStr("1")), ctx.sendParam(keeper), "arbitrage sell at dodo reverse" ); assert.equal( await ctx.BASE.methods.balanceOf(keeper).call(), "252761069524143743" ); }); }); ======= logGas(await UniswapArbitrageurReverse.methods.executeSellArbitrage(decimalStr("1")), ctx.sendParam(keeper), "arbitrage sell at dodo reverse") assert.equal(await ctx.BASE.methods.balanceOf(keeper).call(), "252761069524143743") }) }) >>>>>>> Stashed changes describe("revert cases", () => { it("price not match", async () => { await ctx.setOraclePrice(decimalStr("200")); await assert.rejects( UniswapArbitrageurReverse.methods .executeBuyArbitrage(decimalStr("1")) .send(ctx.sendParam(keeper)), /NOT_PROFITABLE/ ); await assert.rejects( UniswapArbitrageurReverse.methods .executeSellArbitrage(decimalStr("1")) .send(ctx.sendParam(keeper)), /NOT_PROFITABLE/ ); }); }); });