-
-
Save johngrantuk/30d41d88b9da7f6412b766f2fa988b3c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { assert, expect } from 'chai'; | |
import { ethers, ethereum } from "@nomiclabs/buidler"; | |
import { Signer, utils } from "ethers"; | |
const verbose = process.env.VERBOSE; | |
const Decimal = require('decimal.js'); | |
const { calcRelativeDiff } = require('./lib/calc_comparisons'); | |
const errorDelta = 10 ** -8; | |
describe('ExchangeProxy Smart Swaps', function(){ | |
const toWei = utils.parseEther; | |
const fromWei = utils.formatEther; | |
const MAX = ethers.constants.MaxUint256; | |
const errorDelta = 10 ** -8; | |
let registry: any; | |
let factory: any; | |
let REGISTRY: any; | |
let WETH: string; | |
let MKR: string; | |
let ETH: string = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; | |
let weth: any; | |
let mkr: any; | |
let proxy: any; | |
let _POOLS: any[] =[]; | |
let _pools: any[] =[]; | |
let PROXY: string; | |
let admin: string; | |
before(async () => { | |
const BRegistry = await ethers.getContractFactory('BRegistry'); | |
const BFactory = await ethers.getContractFactory('BFactory'); | |
const BPool = await ethers.getContractFactory('BPool'); | |
const TToken = await ethers.getContractFactory('TToken'); | |
const ExchangeProxy = await ethers.getContractFactory("ExchangeProxy"); | |
const Weth9 = await ethers.getContractFactory('WETH9'); | |
const [adminSigner] = await ethers.getSigners(); | |
admin = await adminSigner.getAddress(); | |
factory = await BFactory.deploy(); | |
await factory.deployed(); | |
registry = await BRegistry.deploy(factory.address); | |
await registry.deployed(); | |
mkr = await TToken.deploy('Maker', 'MKR', 18); | |
await mkr.deployed(); | |
MKR = mkr.address; | |
let weth9 = await Weth9.deploy(); | |
await weth9.deployed(); | |
WETH = weth9.address; | |
proxy = await ExchangeProxy.deploy(WETH); | |
await proxy.deployed(); | |
PROXY = proxy.address; | |
await proxy.setRegistry(registry.address); | |
await weth9.approve(PROXY, MAX); | |
await mkr.approve(PROXY, MAX); | |
// Admin balances | |
await weth9.deposit({ value: toWei('10000000000') }); | |
await mkr.mint(admin, toWei('1000000000000000000000')); | |
// Copy pools printed by https://github.com/balancer-labs/python-SOR/blob/master/Onchain_SOR_test_comparison.py | |
// For the following inputs: | |
// num_pools = 5 # Number of pools available for this pair | |
// max_n_pools = 4 | |
// swap_type = "swapExactOut" | |
// input_amount = 100000 # Number of tokens in the trader wants to sell | |
// output_token_eth_price = 0 # One output token buys 0.01 eth | |
// seed = 1 | |
let poolsData = [ | |
{ 'Bmkr': 1033191.1981189704, | |
'Bweth': 21709.92411864851, | |
'Wmkr': 8.261291241849618, | |
'Wweth': 1.7387087581503824, | |
'fee': 0.015}, | |
{ 'Bmkr': 911870.2026231368, | |
'Bweth': 30347.518852549234, | |
'Wmkr': 7.509918308978633, | |
'Wweth': 2.4900816910213672, | |
'fee': 0.025}, | |
{ 'Bmkr': 1199954.250073062, | |
'Bweth': 72017.58337846321, | |
'Wmkr': 6.235514183655618, | |
'Wweth': 3.764485816344382, | |
'fee': 0.01}, | |
{ 'Bmkr': 1079066.970947264, | |
'Bweth': 77902.62602094973, | |
'Wmkr': 5.8258602061546405, | |
'Wweth': 4.1741397938453595, | |
'fee': 0.01}, | |
{ 'Bmkr': 1141297.6436731548, | |
'Bweth': 128034.7686206643, | |
'Wmkr': 4.689466127973144, | |
'Wweth': 5.310533872026856, | |
'fee': 0.005} | |
] | |
for (var i = 0; i < poolsData.length; i++) { | |
let poolAddr = await factory.callStatic.newBPool(); | |
_POOLS.push(poolAddr); | |
await factory.newBPool(); | |
let poolContract = await ethers.getContractAt("BPool", poolAddr); | |
_pools.push(poolContract); | |
await weth9.approve(_POOLS[i], MAX); | |
await mkr.approve(_POOLS[i], MAX); | |
await _pools[i].bind(WETH, toWei(poolsData[i]['Bweth'].toString()), toWei(poolsData[i]['Wweth'].toString())); | |
await _pools[i].bind(MKR, toWei(poolsData[i]['Bmkr'].toString()), toWei(poolsData[i]['Wmkr'].toString())); | |
await _pools[i].setSwapFee(toWei(poolsData[i]['fee'].toString())); | |
await _pools[i].finalize(); | |
/* | |
console.log("Pool "+i.toString()+": "+_POOLS[i]+", Liquidity WETH-MKR: "+ | |
await registry.getNormalizedLiquidity.call(MKR, WETH, _POOLS[i])) | |
*/ | |
} | |
// Proposing registry. NOTICE _POOLS[0] has been left out since it would make up less than 10% of total liquidity | |
await registry.addPools([_POOLS[1], _POOLS[2], _POOLS[3], _POOLS[4]], MKR, WETH); | |
await registry.sortPools([MKR, WETH], 10); | |
}); | |
it('joinswapExternAmountIn, MKR In', async () => { | |
const [, newUserSigner] = await ethers.getSigners(); | |
const newUserAddr = await newUserSigner.getAddress(); | |
const amountIn = toWei('1000'); | |
await mkr.connect(newUserSigner).approve(PROXY, MAX); | |
await mkr.mint(newUserAddr, amountIn); | |
const startingMkrBalance = await mkr.balanceOf(newUserAddr); | |
const startingBptBalance = await _pools[1].balanceOf(newUserAddr); | |
expect(startingBptBalance).to.equal(0); | |
expect(startingMkrBalance).to.equal(amountIn); | |
const poolAmountOut = await proxy.connect(newUserSigner).callStatic.joinswapExternAmountIn( | |
_POOLS[1], | |
MKR, | |
amountIn, | |
toWei('0') | |
); | |
expect(poolAmountOut.toString()).to.equal('81833525388142100'); | |
await proxy.connect(newUserSigner).joinswapExternAmountIn( | |
_POOLS[1], | |
MKR, | |
amountIn, | |
toWei('0'), | |
{ | |
gasPrice: 0 | |
} | |
); | |
const endingMkrBalance = await mkr.balanceOf(newUserAddr); | |
const endingBptBalance = await _pools[1].balanceOf(newUserAddr); | |
expect(endingMkrBalance).to.equal(0); | |
expect(endingBptBalance).to.equal(poolAmountOut); | |
}); | |
it('exitswapExternAmountOut, MKR Out', async () => { | |
const [, newUserSigner] = await ethers.getSigners(); | |
const newUserAddr = await newUserSigner.getAddress(); | |
const amountOut = toWei('100'); | |
await _pools[1].connect(newUserSigner).approve(PROXY, MAX); | |
const startingMkrBalance = await mkr.balanceOf(newUserAddr); | |
const startingBptBalance = await _pools[1].balanceOf(newUserAddr); | |
expect(startingMkrBalance).to.equal(0); | |
const poolAmountIn = await proxy.connect(newUserSigner).callStatic.exitswapExternAmountOut( | |
_POOLS[1], | |
MKR, | |
amountOut, | |
startingBptBalance | |
); | |
await proxy.connect(newUserSigner).exitswapExternAmountOut( | |
_POOLS[1], | |
MKR, | |
amountOut, | |
startingBptBalance, | |
{ | |
gasPrice: 0 | |
} | |
); | |
const endingMkrBalance = await mkr.balanceOf(newUserAddr); | |
const endingBptBalance = await _pools[1].balanceOf(newUserAddr); | |
expect(endingMkrBalance).to.equal(amountOut); | |
expect(endingBptBalance).to.equal(startingBptBalance.sub(poolAmountIn)); | |
}); | |
it('joinswapExternAmountIn, ETH In', async () => { | |
const [, newUserSigner] = await ethers.getSigners(); | |
const newUserAddr = await newUserSigner.getAddress(); | |
const amountIn = toWei('1000'); | |
const startingEthBalance = await newUserSigner.getBalance(); | |
const startingBptBalance = await _pools[1].balanceOf(newUserAddr); | |
const poolAmountOut = await proxy.connect(newUserSigner).callStatic.joinswapExternAmountIn( | |
_POOLS[1], | |
ETH, | |
amountIn, | |
toWei('0'), | |
{ | |
value: amountIn | |
} | |
); | |
let tx = await proxy.connect(newUserSigner).joinswapExternAmountIn( | |
_POOLS[1], | |
ETH, | |
amountIn, | |
toWei('0'), | |
{ | |
gasPrice: 0, | |
value: amountIn | |
} | |
); | |
const endingEthBalance = await newUserSigner.getBalance(); | |
const endingBptBalance = await _pools[1].balanceOf(newUserAddr); | |
expect(endingEthBalance).to.equal(startingEthBalance.sub(amountIn)); | |
expect(poolAmountOut).to.equal(endingBptBalance.sub(startingBptBalance)); | |
}); | |
it('exitswapExternAmountOut, ETH Out', async () => { | |
const [, newUserSigner] = await ethers.getSigners(); | |
const newUserAddr = await newUserSigner.getAddress(); | |
const amountOut = toWei('100'); | |
const startingEthBalance = await newUserSigner.getBalance(); | |
const startingBptBalance = await _pools[1].balanceOf(newUserAddr); | |
const poolAmountIn = await proxy.connect(newUserSigner).callStatic.exitswapExternAmountOut( | |
_POOLS[1], | |
ETH, | |
amountOut, | |
startingBptBalance, | |
{ | |
gasPrice: 0 | |
} | |
); | |
await proxy.connect(newUserSigner).exitswapExternAmountOut( | |
_POOLS[1], | |
ETH, | |
amountOut, | |
startingBptBalance, | |
{ | |
gasPrice: 0 | |
} | |
); | |
// 999999998999.999291088 | |
// 999999999099.999291088 | |
const endingEthBalance = await newUserSigner.getBalance(); | |
const endingBptBalance = await _pools[1].balanceOf(newUserAddr); | |
console.log(startingEthBalance.toString()); | |
console.log(endingEthBalance.toString()); | |
expect(endingEthBalance).to.equal(startingEthBalance.add(amountOut)); | |
expect(endingBptBalance).to.equal(startingBptBalance.sub(poolAmountIn)); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment