199 lines
6.9 KiB
TypeScript
199 lines
6.9 KiB
TypeScript
import path from 'path'
|
|
import chai from 'chai'
|
|
import { solidity, createMockProvider, getWallets, createFixtureLoader } from 'ethereum-waffle'
|
|
import { Contract } from 'ethers'
|
|
import { BigNumber, bigNumberify } from 'ethers/utils'
|
|
|
|
import { expandTo18Decimals } from './shared/utilities'
|
|
import { exchangeFixture, ExchangeFixture } from './shared/fixtures'
|
|
|
|
chai.use(solidity)
|
|
const { expect } = chai
|
|
|
|
describe('UniswapV2', () => {
|
|
const provider = createMockProvider(path.join(__dirname, '..', 'waffle.json'))
|
|
const [wallet] = getWallets(provider)
|
|
const loadFixture = createFixtureLoader(provider, [wallet])
|
|
|
|
let token0: Contract
|
|
let token1: Contract
|
|
let exchange: Contract
|
|
beforeEach(async () => {
|
|
const { token0: _token0, token1: _token1, exchange: _exchange } = (await loadFixture(
|
|
exchangeFixture as any
|
|
)) as ExchangeFixture
|
|
token0 = _token0
|
|
token1 = _token1
|
|
exchange = _exchange
|
|
})
|
|
|
|
it('getAmountOutput', async () => {
|
|
const testCases: BigNumber[][] = [
|
|
[1, 5, 10],
|
|
[1, 10, 5],
|
|
|
|
[2, 5, 10],
|
|
[2, 10, 5],
|
|
|
|
[1, 10, 10],
|
|
[1, 100, 100],
|
|
[1, 1000, 1000]
|
|
].map(a => a.map((n: number) => expandTo18Decimals(n)))
|
|
|
|
const expectedOutputs: BigNumber[] = [
|
|
'1662497915624478906',
|
|
'0453305446940074565',
|
|
|
|
'2851015155847869602',
|
|
'0831248957812239453',
|
|
|
|
'0906610893880149131',
|
|
'0987158034397061298',
|
|
'0996006981039903216'
|
|
].map((n: string) => bigNumberify(n))
|
|
|
|
const outputs = await Promise.all(testCases.map(a => exchange.getAmountOutput(...a)))
|
|
|
|
expect(outputs).to.deep.eq(expectedOutputs)
|
|
})
|
|
|
|
it('mintLiquidity', async () => {
|
|
const token0Amount = expandTo18Decimals(1)
|
|
const token1Amount = expandTo18Decimals(4)
|
|
const expectedLiquidity = expandTo18Decimals(2)
|
|
|
|
await token0.transfer(exchange.address, token0Amount)
|
|
await token1.transfer(exchange.address, token1Amount)
|
|
await expect(exchange.connect(wallet).mintLiquidity(wallet.address))
|
|
.to.emit(exchange, 'LiquidityMinted')
|
|
.withArgs(
|
|
wallet.address,
|
|
wallet.address,
|
|
token0Amount,
|
|
token1Amount,
|
|
token0Amount,
|
|
token1Amount,
|
|
expectedLiquidity
|
|
)
|
|
|
|
expect(await exchange.totalSupply()).to.eq(expectedLiquidity)
|
|
expect(await exchange.balanceOf(wallet.address)).to.eq(expectedLiquidity)
|
|
})
|
|
|
|
async function addLiquidity(token0Amount: BigNumber, token1Amount: BigNumber) {
|
|
await token0.transfer(exchange.address, token0Amount)
|
|
await token1.transfer(exchange.address, token1Amount)
|
|
await exchange.connect(wallet).mintLiquidity(wallet.address)
|
|
}
|
|
|
|
// it('swap:gas', async () => {
|
|
// const token0Amount = expandTo18Decimals(5)
|
|
// const token1Amount = expandTo18Decimals(10)
|
|
// await addLiquidity(token0Amount, token1Amount)
|
|
|
|
// const swapAmount = expandTo18Decimals(1)
|
|
// await token0.transfer(exchange.address, swapAmount)
|
|
// await exchange.connect(wallet).swap(token0.address, wallet.address)
|
|
|
|
// await token0.transfer(exchange.address, swapAmount)
|
|
// console.log((await exchange.estimate.swap(token0.address, wallet.address)).toString())
|
|
// })
|
|
|
|
// it('swap:gas', async () => {
|
|
// const token0Amount = expandTo18Decimals(10)
|
|
// const token1Amount = expandTo18Decimals(5)
|
|
// await addLiquidity(token0Amount, token1Amount)
|
|
|
|
// const swapAmount = expandTo18Decimals(1)
|
|
// await token1.transfer(exchange.address, swapAmount)
|
|
// await exchange.connect(wallet).swap(token1.address, wallet.address)
|
|
|
|
// await token1.transfer(exchange.address, swapAmount)
|
|
// console.log((await exchange.estimate.swap(token1.address, wallet.address)).toString())
|
|
// })
|
|
|
|
it('swap', async () => {
|
|
const token0Amount = expandTo18Decimals(5)
|
|
const token1Amount = expandTo18Decimals(10)
|
|
await addLiquidity(token0Amount, token1Amount)
|
|
|
|
const swapAmount = expandTo18Decimals(1)
|
|
const expectedOutputAmount = bigNumberify('1662497915624478906')
|
|
await token0.transfer(exchange.address, swapAmount)
|
|
expect(await exchange.swap)
|
|
await expect(exchange.connect(wallet).swap(token0.address, wallet.address))
|
|
.to.emit(exchange, 'Swap')
|
|
.withArgs(
|
|
wallet.address,
|
|
wallet.address,
|
|
swapAmount,
|
|
expectedOutputAmount,
|
|
token0Amount.add(swapAmount),
|
|
token1Amount.sub(expectedOutputAmount),
|
|
token0.address
|
|
)
|
|
|
|
expect(await token0.balanceOf(exchange.address)).to.eq(token0Amount.add(swapAmount))
|
|
expect(await token1.balanceOf(exchange.address)).to.eq(token1Amount.sub(expectedOutputAmount))
|
|
|
|
const totalSupplyToken1 = await token1.totalSupply()
|
|
expect(await token1.balanceOf(wallet.address)).to.eq(totalSupplyToken1.sub(token1Amount).add(expectedOutputAmount))
|
|
})
|
|
|
|
it('burnLiquidity', async () => {
|
|
const token0Amount = expandTo18Decimals(3)
|
|
const token1Amount = expandTo18Decimals(3)
|
|
await addLiquidity(token0Amount, token1Amount)
|
|
|
|
const liquidity = expandTo18Decimals(3)
|
|
await exchange.connect(wallet).transfer(exchange.address, liquidity)
|
|
await expect(exchange.connect(wallet).burnLiquidity(wallet.address))
|
|
.to.emit(exchange, 'LiquidityBurned')
|
|
.withArgs(wallet.address, wallet.address, token0Amount, token1Amount, bigNumberify(0), bigNumberify(0), liquidity)
|
|
|
|
expect(await exchange.balanceOf(wallet.address)).to.eq(0)
|
|
expect(await token0.balanceOf(exchange.address)).to.eq(0)
|
|
expect(await token1.balanceOf(exchange.address)).to.eq(0)
|
|
|
|
const totalSupplyToken0 = await token0.totalSupply()
|
|
const totalSupplyToken1 = await token1.totalSupply()
|
|
|
|
expect(await token0.balanceOf(wallet.address)).to.eq(totalSupplyToken0)
|
|
expect(await token1.balanceOf(wallet.address)).to.eq(totalSupplyToken1)
|
|
})
|
|
|
|
it('getReserves', async () => {
|
|
expect(await exchange.getReserves()).to.deep.eq([0, 0].map(n => bigNumberify(n)))
|
|
|
|
const token0Amount = expandTo18Decimals(3)
|
|
const token1Amount = expandTo18Decimals(3)
|
|
await addLiquidity(token0Amount, token1Amount)
|
|
|
|
expect(await exchange.getReserves()).to.deep.eq([token0Amount, token1Amount])
|
|
})
|
|
|
|
// it('getReservesCumulative', async () => {
|
|
// await expect(exchange.getReservesCumulative()).to.be.revertedWith('UniswapV2: NOT_INITIALIZED')
|
|
|
|
// const token0Amount = expandTo18Decimals(3)
|
|
// const token1Amount = expandTo18Decimals(3)
|
|
// await addLiquidity(token0Amount, token1Amount)
|
|
|
|
// expect(await exchange.getReservesCumulative()).to.deep.eq(
|
|
// [0, 0, 0, 0].map((n: number): BigNumber => bigNumberify(n))
|
|
// )
|
|
|
|
// const dummySwapAmount = bigNumberify(1)
|
|
// await token0.transfer(exchange.address, dummySwapAmount)
|
|
// await exchange.connect(wallet).swap(token0.address, wallet.address)
|
|
|
|
// const reservesCumulativePost = await exchange.getReservesCumulative()
|
|
// expect(reservesCumulativePost).to.deep.eq([
|
|
// token0Amount.mul(bigNumberify(2)),
|
|
// token1Amount.mul(bigNumberify(2)),
|
|
// bigNumberify(0),
|
|
// bigNumberify(0)
|
|
// ])
|
|
// })
|
|
})
|