This commit is contained in:
Noah Zinsmeister
2019-11-06 17:23:03 -05:00
parent 8cb70d07b2
commit 710adc3254
15 changed files with 399 additions and 315 deletions

View File

@ -118,10 +118,8 @@ describe('ERC20', () => {
it('transfer:fail', async () => {
await expect(token.transfer(other.address, TOKEN_DETAILS.totalSupply.add(1))).to.be.revertedWith(
'SafeMath256: subtraction overflow'
)
await expect(token.connect(other).transfer(wallet.address, 1)).to.be.revertedWith(
'SafeMath256: subtraction overflow'
'ds-math-sub-underflow'
)
await expect(token.connect(other).transfer(wallet.address, 1)).to.be.revertedWith('ds-math-sub-underflow')
})
})

View File

@ -4,14 +4,22 @@ import { solidity, createMockProvider, getWallets, createFixtureLoader, deployCo
import { Contract } from 'ethers'
import { BigNumber, bigNumberify } from 'ethers/utils'
import { expandTo18Decimals } from './shared/utilities'
import { expandTo18Decimals, mineBlocks } from './shared/utilities'
import { exchangeFixture, ExchangeFixture } from './shared/fixtures'
import Oracle from '../build/Oracle.json'
const ONE_DAY = 60 * 60 * 24
chai.use(solidity)
const { expect } = chai
interface OracleSnapshot {
cumulativeReserves: BigNumber[]
blockNumber: number
time: number
}
describe('Oracle', () => {
const provider = createMockProvider(path.join(__dirname, '..', 'waffle.json'))
const [wallet] = getWallets(provider)
@ -37,9 +45,18 @@ describe('Oracle', () => {
await exchange.connect(wallet).mintLiquidity(wallet.address)
}
async function swap(token: Contract, amount: BigNumber) {
await token.transfer(exchange.address, amount)
await exchange.connect(wallet).swap(token.address, wallet.address)
async function swap(inputToken: Contract, amount: BigNumber) {
const token0 = await exchange.token0()
const reserves = await exchange.getReserves()
const inputReserve = inputToken.address === token0 ? reserves[0] : reserves[1]
const outputReserve = inputToken.address === token0 ? reserves[1] : reserves[0]
const outputAmount = await exchange.getAmountOutput(amount, inputReserve, outputReserve)
await inputToken.transfer(exchange.address, amount)
await exchange.connect(wallet).swap(inputToken.address, wallet.address)
return outputAmount
}
it('exchange, getCurrentPrice', async () => {
@ -47,15 +64,63 @@ describe('Oracle', () => {
expect(await oracle.getCurrentPrice()).to.deep.eq([0, 0].map(n => bigNumberify(n)))
})
async function getOracleSnapshot(): Promise<OracleSnapshot> {
const cumulativeReserves = await exchange.getReservesCumulativeAndOverflows()
const blockNumber = await provider.getBlockNumber()
const time = (await provider.getBlock(blockNumber)).timestamp
return {
cumulativeReserves,
blockNumber,
time
}
}
// function getExpectedOraclePrice(
// preSnapshot: OracleSnapshot,
// postSnapshot: OracleSnapshot,
// oldPrice: BigNumber[],
// elapsedTime: number
// ) {
// return 1
// }
it('updateCurrentPrice', async () => {
const token0Amount = expandTo18Decimals(10)
const token1Amount = expandTo18Decimals(5)
const token0Amount = expandTo18Decimals(5)
const token1Amount = expandTo18Decimals(10)
await addLiquidity(token0Amount, token1Amount)
await oracle.connect(wallet).initialize()
await swap(token0, bigNumberify(1))
await oracle.connect(wallet).updateCurrentPrice()
await oracle.connect(wallet).initialize()
expect(await oracle.getCurrentPrice()).to.deep.eq([0, 0].map(n => bigNumberify(n)))
await oracle.connect(wallet).activate()
expect(await oracle.getCurrentPrice()).to.deep.eq([token0Amount, token1Amount])
const preSwapSnapshot = await getOracleSnapshot()
const swapAmount = expandTo18Decimals(5)
const expectedToken1Amount = await swap(token0, swapAmount)
const postSwapToken0Amount = token0Amount.add(swapAmount)
const postSwapToken1Amount = token1Amount.sub(expectedToken1Amount)
const postSwapSnapshot = await getOracleSnapshot()
const elapsedBlocks = postSwapSnapshot.blockNumber - preSwapSnapshot.blockNumber
expect(elapsedBlocks).to.eq(2)
await oracle.connect(wallet).update()
const elapsedTime = postSwapSnapshot.time - preSwapSnapshot.time
if (elapsedTime === 0) {
expect(await oracle.getCurrentPrice()).to.deep.eq([token0Amount, token1Amount])
} else {
console.log('uh oh!')
// expect(await oracle.getCurrentPrice()).to.deep.eq([token0Amount, token1Amount])
}
// console.log((await oracle.getCurrentPrice()).map((p: BigNumber): string => p.toString()))
// await mineBlocks(provider, 1, timePost + 60 * 60 * (24 / 2))
// await oracle.connect(wallet).update()
})
})

View File

@ -94,7 +94,15 @@ describe('UniswapV2', () => {
const expectedOutputAmount = bigNumberify('1662497915624478906')
await token0.transfer(exchange.address, swapAmount)
await expect(exchange.connect(wallet).swap(token0.address, wallet.address))
console.log(await exchange.estimate.swap(token0.address, wallet.address))
await expect(
exchange
.connect(wallet)
.swap(token0.address, wallet.address)
.then((a: any) => {
console.log(a)
})
)
.to.emit(exchange, 'Swap')
.withArgs(wallet.address, wallet.address, token0.address, swapAmount, expectedOutputAmount)
@ -127,31 +135,36 @@ describe('UniswapV2', () => {
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)))
// 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('getReservesCumulativeAndOverflows', async () => {
expect(await exchange.getReservesCumulativeAndOverflows()).to.deep.eq([0, 0, 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 () => {
expect(await exchange.getReservesCumulative()).to.deep.eq([0, 0].map(n => bigNumberify(n)))
const token0Amount = expandTo18Decimals(3)
const token1Amount = expandTo18Decimals(3)
await addLiquidity(token0Amount, token1Amount)
const reservesCumulativePre = await exchange.getReservesCumulative()
expect(reservesCumulativePre).to.deep.eq([0, 0].map(n => bigNumberify(n)))
const reservesCumulativePre = await exchange.getReservesCumulativeAndOverflows()
expect(reservesCumulativePre).to.deep.eq([0, 0, 0, 0].map(n => 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))])
const reservesCumulativePost = await exchange.getReservesCumulativeAndOverflows()
expect(reservesCumulativePost).to.deep.eq([
token0Amount.mul(bigNumberify(2)),
token1Amount.mul(bigNumberify(2)),
0,
0
])
})
})

View File

@ -1,3 +1,4 @@
import { providers } from 'ethers'
import { BigNumber, bigNumberify, getAddress, keccak256, solidityPack } from 'ethers/utils'
import { CHAIN_ID } from './constants'
@ -48,3 +49,27 @@ export function getCreate2Address(
return getAddress(`0x${keccak256(sanitizedInputs).slice(-40)}`)
}
async function mineBlock(provider: providers.Web3Provider, timestamp?: number): Promise<void> {
await new Promise((resolve, reject) => {
;(provider._web3Provider.sendAsync as any)(
{ jsonrpc: '2.0', method: 'evm_mine', params: timestamp ? [timestamp] : [] },
(error: any, result: any): void => {
if (error) {
reject(error)
} else {
resolve(result)
}
}
)
})
}
export async function mineBlocks(
provider: providers.Web3Provider,
numberOfBlocks: number,
timestamp?: number
): Promise<void> {
await Promise.all([...Array(numberOfBlocks - 1)].map(() => mineBlock(provider)))
await mineBlock(provider, timestamp)
}