changes
This commit is contained in:
@ -56,14 +56,18 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
initialize(chainId);
|
||||
}
|
||||
|
||||
function getReservesCumulativeAndOverflows() external view returns (uint128, uint128, uint128, uint128) {
|
||||
function getReserves() external view returns (uint128, uint128) {
|
||||
return (reserves.token0, reserves.token1);
|
||||
}
|
||||
|
||||
function getReservesCumulative() external view returns (uint128, uint128, uint128, uint128) {
|
||||
require(blockNumberLast > 0, "UniswapV2: NOT_INITIALIZED");
|
||||
|
||||
TokenData memory reservesCumulativeNext;
|
||||
TokenData memory reservesCumulativeOverflowsNext;
|
||||
// replicate the logic in update
|
||||
if (block.number > blockNumberLast) {
|
||||
uint128 blocksElapsed = block.number.sub(blockNumberLast).downcast128();
|
||||
uint128 blocksElapsed = (block.number - blockNumberLast).downcast128();
|
||||
|
||||
TokenData memory remaindersMul;
|
||||
TokenData memory overflowsMul;
|
||||
@ -91,6 +95,10 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
);
|
||||
}
|
||||
|
||||
function getBlockNumberLast() external view returns (uint256) {
|
||||
return blockNumberLast;
|
||||
}
|
||||
|
||||
function getAmountOutput(uint128 amountInput, uint128 reserveInput, uint128 reserveOutput)
|
||||
public pure returns (uint128 amountOutput)
|
||||
{
|
||||
@ -101,12 +109,14 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
amountOutput = (numerator / denominator).downcast128();
|
||||
}
|
||||
|
||||
function update(TokenData memory reservesNext) private {
|
||||
function update(TokenData memory balances) private {
|
||||
// if any blocks have gone by since the last time this function was called, we have to update
|
||||
if (block.number > blockNumberLast) {
|
||||
// make sure that this isn't the first time this function is being called
|
||||
if (blockNumberLast > 0) {
|
||||
uint128 blocksElapsed = block.number.sub(blockNumberLast).downcast128();
|
||||
uint128 blocksElapsed = (block.number - blockNumberLast).downcast128();
|
||||
|
||||
// TODO address ratio of sum / sum of ratios / price accumulator issue
|
||||
|
||||
// multiply previous reserves by elapsed blocks in an overflow-safe way
|
||||
TokenData memory remaindersMul;
|
||||
@ -120,10 +130,16 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
(reservesCumulative.token1, overflowsAdd.token1) = reservesCumulative.token1.oadd(remaindersMul.token1);
|
||||
|
||||
// update cumulative reserves overflows
|
||||
reservesCumulativeOverflows = TokenData({
|
||||
token0: reservesCumulativeOverflows.token0.add(overflowsMul.token0.add(overflowsAdd.token0)),
|
||||
token1: reservesCumulativeOverflows.token1.add(overflowsMul.token1.add(overflowsAdd.token1))
|
||||
TokenData memory overflows = TokenData({
|
||||
token0: overflowsMul.token0.add(overflowsAdd.token0),
|
||||
token1: overflowsMul.token1.add(overflowsAdd.token1)
|
||||
});
|
||||
if (overflows.token0 > 0 || overflows.token1 > 0) {
|
||||
reservesCumulativeOverflows = TokenData({
|
||||
token0: reservesCumulativeOverflows.token0.add(overflows.token0),
|
||||
token1: reservesCumulativeOverflows.token1.add(overflows.token1)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// update the last block number
|
||||
@ -131,7 +147,7 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
}
|
||||
|
||||
// update reserves
|
||||
reserves = reservesNext;
|
||||
reserves = balances;
|
||||
}
|
||||
|
||||
function mintLiquidity(address recipient) external lock returns (uint256 liquidity) {
|
||||
@ -139,7 +155,6 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
token0: IERC20(token0).balanceOf(address(this)).downcast128(),
|
||||
token1: IERC20(token1).balanceOf(address(this)).downcast128()
|
||||
});
|
||||
|
||||
TokenData memory amounts = TokenData({
|
||||
token0: balances.token0.sub(reserves.token0),
|
||||
token1: balances.token1.sub(reserves.token1)
|
||||
@ -161,11 +176,11 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
|
||||
function burnLiquidity(address recipient) external lock returns (uint128 amountToken0, uint128 amountToken1) {
|
||||
uint256 liquidity = balanceOf[address(this)];
|
||||
|
||||
TokenData memory amounts = TokenData({
|
||||
token0: (amountToken0 = (liquidity.mul(reserves.token0) / totalSupply).downcast128()),
|
||||
token1: (amountToken1 = (liquidity.mul(reserves.token1) / totalSupply).downcast128())
|
||||
});
|
||||
|
||||
require(amounts.token0 == 0 || safeTransfer(token0, recipient, amounts.token0), "UniswapV2: TRANSFER_0_FAILED");
|
||||
require(amounts.token1 == 0 || safeTransfer(token1, recipient, amounts.token1), "UniswapV2: TRANSFER_1_FAILED");
|
||||
|
||||
@ -178,33 +193,22 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
}
|
||||
|
||||
function swap(address input, address recipient) external lock returns (uint128 amountOutput) {
|
||||
uint128 balanceInput = IERC20(input).balanceOf(address(this)).downcast128();
|
||||
|
||||
TokenData memory amounts;
|
||||
TokenData memory balances;
|
||||
TokenData memory amounts;
|
||||
|
||||
if (input == token0) {
|
||||
uint128 amountInput = balanceInput.sub(reserves.token0);
|
||||
amounts = TokenData({
|
||||
token0: amountInput,
|
||||
token1: (amountOutput = getAmountOutput(amountInput, reserves.token0, reserves.token1))
|
||||
});
|
||||
require(amounts.token1 == 0 || safeTransfer(token1, recipient, amounts.token1), "UniswapV2: TRANSFER_1_FAILED");
|
||||
balances = TokenData({
|
||||
token0: balanceInput,
|
||||
token1: IERC20(token1).balanceOf(address(this)).downcast128()
|
||||
});
|
||||
balances.token0 = IERC20(input).balanceOf(address(this)).downcast128();
|
||||
amounts.token0 = balances.token0.sub(reserves.token0);
|
||||
amounts.token1 = (amountOutput = getAmountOutput(amounts.token0, reserves.token0, reserves.token1));
|
||||
require(safeTransfer(token1, recipient, amounts.token1), "UniswapV2: TRANSFER_1_FAILED");
|
||||
balances.token1 = IERC20(token1).balanceOf(address(this)).downcast128();
|
||||
} else {
|
||||
require(input == token1, "UniswapV2: INVALID_INPUT");
|
||||
uint128 amountInput = balanceInput.sub(reserves.token1);
|
||||
amounts = TokenData({
|
||||
token0: (amountOutput = getAmountOutput(amountInput, reserves.token1, reserves.token0)),
|
||||
token1: amountInput
|
||||
});
|
||||
require(amounts.token0 == 0 || safeTransfer(token0, recipient, amounts.token0), "UniswapV2: TRANSFER_0_FAILED");
|
||||
balances = TokenData({
|
||||
token0: IERC20(token0).balanceOf(address(this)).downcast128(),
|
||||
token1: balanceInput
|
||||
});
|
||||
balances.token1 = IERC20(input).balanceOf(address(this)).downcast128();
|
||||
amounts.token1 = balances.token1.sub(reserves.token1);
|
||||
amounts.token0 = (amountOutput = getAmountOutput(amounts.token1, reserves.token1, reserves.token0));
|
||||
require(safeTransfer(token0, recipient, amounts.token0), "UniswapV2: TRANSFER_0_FAILED");
|
||||
balances.token0 = IERC20(token0).balanceOf(address(this)).downcast128();
|
||||
}
|
||||
|
||||
update(balances);
|
||||
|
||||
@ -15,7 +15,9 @@ interface IUniswapV2 {
|
||||
function token0() external view returns (address);
|
||||
function token1() external view returns (address);
|
||||
|
||||
function getReservesCumulativeAndOverflows() external view returns (uint128, uint128, uint128, uint128);
|
||||
function getReserves() external view returns (uint128, uint128);
|
||||
function getReservesCumulative() external view returns (uint128, uint128, uint128, uint128);
|
||||
function getBlockNumberLast() external view returns (uint256);
|
||||
|
||||
function getAmountOutput(uint128 amountInput, uint128 reserveInput, uint128 reserveOutput)
|
||||
external pure returns (uint128 amountOutput);
|
||||
|
||||
@ -23,35 +23,48 @@ contract Oracle {
|
||||
uint128 constant period = 1 days;
|
||||
|
||||
OracleStates private state = OracleStates.NeedsInitialization;
|
||||
|
||||
TokenData private reservesCumulative;
|
||||
TimeData private lastUpdate;
|
||||
TokenData private reservesCumulativeOverflows;
|
||||
|
||||
TokenData private currentPrice;
|
||||
|
||||
TimeData private updateLast;
|
||||
|
||||
constructor(address _exchange) public {
|
||||
exchange = _exchange;
|
||||
}
|
||||
|
||||
function getReservesCumulative() private view returns (TokenData memory) {
|
||||
IUniswapV2 uniswapV2 = IUniswapV2(exchange);
|
||||
(uint128 reservesCumulativeToken0, uint128 reservesCumulativeToken1,,) = uniswapV2.getReservesCumulativeAndOverflows();
|
||||
return TokenData({
|
||||
token0: reservesCumulativeToken0,
|
||||
token1: reservesCumulativeToken1
|
||||
});
|
||||
function getReservesCumulative() private view returns (TokenData memory, TokenData memory) {
|
||||
(
|
||||
uint128 reservesCumulativeToken0,
|
||||
uint128 reservesCumulativeToken1,
|
||||
uint128 reservesCumulativeOverflowsToken0,
|
||||
uint128 reservesCumulativeOverflowsToken1
|
||||
) = IUniswapV2(exchange).getReservesCumulative();
|
||||
return (
|
||||
TokenData(reservesCumulativeToken0, reservesCumulativeToken1),
|
||||
TokenData(reservesCumulativeOverflowsToken0, reservesCumulativeOverflowsToken1)
|
||||
);
|
||||
}
|
||||
|
||||
function getTimeData() private view returns (TimeData memory) {
|
||||
return TimeData({
|
||||
blockNumber: block.number.downcast128(),
|
||||
blockTimestamp: block.timestamp.downcast128()
|
||||
});
|
||||
function getNow() private view returns (TimeData memory) {
|
||||
return TimeData(block.number.downcast128(), block.timestamp.downcast128());
|
||||
}
|
||||
|
||||
function reset() private {
|
||||
delete(reservesCumulative);
|
||||
delete(reservesCumulativeOverflows);
|
||||
delete(currentPrice);
|
||||
delete(updateLast);
|
||||
state = OracleStates.NeedsInitialization;
|
||||
}
|
||||
|
||||
function initialize() external {
|
||||
require(state == OracleStates.NeedsInitialization, "Oracle: DOES_NOT_NEED_INITIALIZATION");
|
||||
|
||||
reservesCumulative = getReservesCumulative();
|
||||
lastUpdate = getTimeData();
|
||||
(reservesCumulative, reservesCumulativeOverflows) = getReservesCumulative();
|
||||
updateLast = getNow();
|
||||
|
||||
state = OracleStates.NeedsActivation;
|
||||
}
|
||||
@ -59,14 +72,26 @@ contract Oracle {
|
||||
function activate() external {
|
||||
require(state == OracleStates.NeedsActivation, "Oracle: DOES_NOT_NEED_ACTIVATION");
|
||||
|
||||
// get the current time, ensure it's been >=1 blocks since last update, and record the update
|
||||
TimeData memory currentTime = getTimeData();
|
||||
uint128 blocksElapsed = currentTime.blockNumber - lastUpdate.blockNumber;
|
||||
// get the current time, ensure it's been >=1 blocks since the last update
|
||||
TimeData memory _now = getNow();
|
||||
uint128 blocksElapsed = _now.blockNumber - updateLast.blockNumber;
|
||||
require(blocksElapsed > 0, "Oracle: INSUFFICIENT_BLOCKS_PASSED");
|
||||
lastUpdate = currentTime;
|
||||
|
||||
// get the current cumulative reserves, calculate the deltas, and record the new values
|
||||
TokenData memory reservesCumulativeNext = getReservesCumulative();
|
||||
// get the current cumulative reserves and overflows
|
||||
TokenData memory reservesCumulativeNext;
|
||||
TokenData memory reservesCumulativeOverflowsNext;
|
||||
(reservesCumulativeNext, reservesCumulativeOverflowsNext) = getReservesCumulative();
|
||||
|
||||
// reset if there's been an overflow
|
||||
if (
|
||||
reservesCumulativeOverflows.token0 != reservesCumulativeOverflowsNext.token0 ||
|
||||
reservesCumulativeOverflows.token1 != reservesCumulativeOverflowsNext.token1
|
||||
) {
|
||||
reset();
|
||||
require(false, "Oracle: OVERFLOW");
|
||||
}
|
||||
|
||||
// calculate the deltas, and record the new values
|
||||
TokenData memory deltas = TokenData({
|
||||
token0: reservesCumulativeNext.token0 - reservesCumulative.token0,
|
||||
token1: reservesCumulativeNext.token1 - reservesCumulative.token1
|
||||
@ -79,21 +104,35 @@ contract Oracle {
|
||||
token1: deltas.token1 / blocksElapsed
|
||||
});
|
||||
|
||||
updateLast = _now;
|
||||
|
||||
state = OracleStates.Active;
|
||||
}
|
||||
|
||||
function update() external {
|
||||
require(state == OracleStates.Active, "Oracle: INACTIVE");
|
||||
|
||||
// get the current time, ensure it's been >=1 blocks since last update, and record the update
|
||||
TimeData memory currentTime = getTimeData();
|
||||
uint128 blocksElapsed = currentTime.blockNumber - lastUpdate.blockNumber;
|
||||
// get the current time, ensure it's been >=1 blocks since the last update
|
||||
TimeData memory _now = getNow();
|
||||
uint128 blocksElapsed = _now.blockNumber - updateLast.blockNumber;
|
||||
require(blocksElapsed > 0, "Oracle: INSUFFICIENT_BLOCKS_PASSED");
|
||||
uint128 timeElapsed = currentTime.blockTimestamp - lastUpdate.blockTimestamp;
|
||||
lastUpdate = currentTime;
|
||||
uint128 timeElapsed = _now.blockTimestamp - updateLast.blockTimestamp;
|
||||
|
||||
// get the current cumulative reserves, calculate the deltas, and record the new values
|
||||
TokenData memory reservesCumulativeNext = getReservesCumulative();
|
||||
// get the current cumulative reserves and overflows
|
||||
TokenData memory reservesCumulativeNext;
|
||||
TokenData memory reservesCumulativeOverflowsNext;
|
||||
(reservesCumulativeNext, reservesCumulativeOverflowsNext) = getReservesCumulative();
|
||||
|
||||
// reset if there's been an overflow
|
||||
if (
|
||||
reservesCumulativeOverflows.token0 != reservesCumulativeOverflowsNext.token0 ||
|
||||
reservesCumulativeOverflows.token1 != reservesCumulativeOverflowsNext.token1
|
||||
) {
|
||||
reset();
|
||||
require(false, "Oracle: OVERFLOW");
|
||||
}
|
||||
|
||||
// calculate the deltas, and record the new values
|
||||
TokenData memory deltas = TokenData({
|
||||
token0: reservesCumulativeNext.token0 - reservesCumulative.token0,
|
||||
token1: reservesCumulativeNext.token1 - reservesCumulative.token1
|
||||
@ -115,6 +154,8 @@ contract Oracle {
|
||||
} else {
|
||||
currentPrice = averages;
|
||||
}
|
||||
|
||||
updateLast = _now;
|
||||
}
|
||||
|
||||
function getCurrentPrice() external view returns (uint128, uint128) {
|
||||
|
||||
@ -1,126 +1,126 @@
|
||||
import path from 'path'
|
||||
import chai from 'chai'
|
||||
import { solidity, createMockProvider, getWallets, createFixtureLoader, deployContract } from 'ethereum-waffle'
|
||||
import { Contract } from 'ethers'
|
||||
import { BigNumber, bigNumberify } from 'ethers/utils'
|
||||
// import path from 'path'
|
||||
// import chai from 'chai'
|
||||
// import { solidity, createMockProvider, getWallets, createFixtureLoader, deployContract } from 'ethereum-waffle'
|
||||
// import { Contract } from 'ethers'
|
||||
// import { BigNumber, bigNumberify } from 'ethers/utils'
|
||||
|
||||
import { expandTo18Decimals, mineBlocks } from './shared/utilities'
|
||||
import { exchangeFixture, ExchangeFixture } from './shared/fixtures'
|
||||
// import { expandTo18Decimals, mineBlocks } from './shared/utilities'
|
||||
// import { exchangeFixture, ExchangeFixture } from './shared/fixtures'
|
||||
|
||||
import Oracle from '../build/Oracle.json'
|
||||
// import Oracle from '../build/Oracle.json'
|
||||
|
||||
const ONE_DAY = 60 * 60 * 24
|
||||
// const ONE_DAY = 60 * 60 * 24
|
||||
|
||||
chai.use(solidity)
|
||||
const { expect } = chai
|
||||
// chai.use(solidity)
|
||||
// const { expect } = chai
|
||||
|
||||
interface OracleSnapshot {
|
||||
cumulativeReserves: BigNumber[]
|
||||
blockNumber: number
|
||||
time: number
|
||||
}
|
||||
// interface OracleSnapshot {
|
||||
// cumulativeReserves: BigNumber[]
|
||||
// blockNumber: number
|
||||
// time: number
|
||||
// }
|
||||
|
||||
describe('Oracle', () => {
|
||||
const provider = createMockProvider(path.join(__dirname, '..', 'waffle.json'))
|
||||
const [wallet] = getWallets(provider)
|
||||
const loadFixture = createFixtureLoader(provider, [wallet])
|
||||
// describe('Oracle', () => {
|
||||
// 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
|
||||
let oracle: Contract
|
||||
beforeEach(async () => {
|
||||
const { token0: _token0, token1: _token1, exchange: _exchange } = (await loadFixture(
|
||||
exchangeFixture as any
|
||||
)) as ExchangeFixture
|
||||
token0 = _token0
|
||||
token1 = _token1
|
||||
exchange = _exchange
|
||||
oracle = await deployContract(wallet, Oracle, [exchange.address])
|
||||
})
|
||||
// let token0: Contract
|
||||
// let token1: Contract
|
||||
// let exchange: Contract
|
||||
// let oracle: Contract
|
||||
// beforeEach(async () => {
|
||||
// const { token0: _token0, token1: _token1, exchange: _exchange } = (await loadFixture(
|
||||
// exchangeFixture as any
|
||||
// )) as ExchangeFixture
|
||||
// token0 = _token0
|
||||
// token1 = _token1
|
||||
// exchange = _exchange
|
||||
// oracle = await deployContract(wallet, Oracle, [exchange.address])
|
||||
// })
|
||||
|
||||
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)
|
||||
}
|
||||
// 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)
|
||||
// }
|
||||
|
||||
async function swap(inputToken: Contract, amount: BigNumber) {
|
||||
const token0 = await exchange.token0()
|
||||
const reserves = await exchange.getReserves()
|
||||
// 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)
|
||||
// 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)
|
||||
// await inputToken.transfer(exchange.address, amount)
|
||||
// await exchange.connect(wallet).swap(inputToken.address, wallet.address)
|
||||
|
||||
return outputAmount
|
||||
}
|
||||
// return outputAmount
|
||||
// }
|
||||
|
||||
it('exchange, getCurrentPrice', async () => {
|
||||
expect(await oracle.exchange()).to.eq(exchange.address)
|
||||
expect(await oracle.getCurrentPrice()).to.deep.eq([0, 0].map(n => bigNumberify(n)))
|
||||
})
|
||||
// it('exchange, getCurrentPrice', async () => {
|
||||
// expect(await oracle.exchange()).to.eq(exchange.address)
|
||||
// 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
|
||||
// async function getOracleSnapshot(): Promise<OracleSnapshot> {
|
||||
// const cumulativeReserves = await exchange.getReservesCumulative()
|
||||
// const blockNumber = await provider.getBlockNumber()
|
||||
// const time = (await provider.getBlock(blockNumber)).timestamp
|
||||
|
||||
return {
|
||||
cumulativeReserves,
|
||||
blockNumber,
|
||||
time
|
||||
}
|
||||
}
|
||||
// return {
|
||||
// cumulativeReserves,
|
||||
// blockNumber,
|
||||
// time
|
||||
// }
|
||||
// }
|
||||
|
||||
// function getExpectedOraclePrice(
|
||||
// preSnapshot: OracleSnapshot,
|
||||
// postSnapshot: OracleSnapshot,
|
||||
// oldPrice: BigNumber[],
|
||||
// elapsedTime: number
|
||||
// ) {
|
||||
// return 1
|
||||
// }
|
||||
// // function getExpectedOraclePrice(
|
||||
// // preSnapshot: OracleSnapshot,
|
||||
// // postSnapshot: OracleSnapshot,
|
||||
// // oldPrice: BigNumber[],
|
||||
// // elapsedTime: number
|
||||
// // ) {
|
||||
// // return 1
|
||||
// // }
|
||||
|
||||
it('updateCurrentPrice', async () => {
|
||||
const token0Amount = expandTo18Decimals(5)
|
||||
const token1Amount = expandTo18Decimals(10)
|
||||
await addLiquidity(token0Amount, token1Amount)
|
||||
// // it('updateCurrentPrice', async () => {
|
||||
// // const token0Amount = expandTo18Decimals(5)
|
||||
// // const token1Amount = expandTo18Decimals(10)
|
||||
// // await addLiquidity(token0Amount, token1Amount)
|
||||
|
||||
await oracle.connect(wallet).initialize()
|
||||
expect(await oracle.getCurrentPrice()).to.deep.eq([0, 0].map(n => bigNumberify(n)))
|
||||
// // 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])
|
||||
// // await oracle.connect(wallet).activate()
|
||||
// // expect(await oracle.getCurrentPrice()).to.deep.eq([token0Amount, token1Amount])
|
||||
|
||||
const preSwapSnapshot = await getOracleSnapshot()
|
||||
// // 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 swapAmount = expandTo18Decimals(5)
|
||||
// // const expectedToken1Amount = await swap(token0, swapAmount)
|
||||
// // const postSwapToken0Amount = token0Amount.add(swapAmount)
|
||||
// // const postSwapToken1Amount = token1Amount.sub(expectedToken1Amount)
|
||||
|
||||
const postSwapSnapshot = await getOracleSnapshot()
|
||||
// // const postSwapSnapshot = await getOracleSnapshot()
|
||||
|
||||
const elapsedBlocks = postSwapSnapshot.blockNumber - preSwapSnapshot.blockNumber
|
||||
expect(elapsedBlocks).to.eq(2)
|
||||
// // const elapsedBlocks = postSwapSnapshot.blockNumber - preSwapSnapshot.blockNumber
|
||||
// // expect(elapsedBlocks).to.eq(2)
|
||||
|
||||
await oracle.connect(wallet).update()
|
||||
// // 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])
|
||||
}
|
||||
// // 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()))
|
||||
// // // 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()
|
||||
})
|
||||
})
|
||||
// // // await mineBlocks(provider, 1, timePost + 60 * 60 * (24 / 2))
|
||||
// // // await oracle.connect(wallet).update()
|
||||
// // })
|
||||
// })
|
||||
|
||||
@ -85,6 +85,32 @@ describe('UniswapV2', () => {
|
||||
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)
|
||||
@ -92,17 +118,9 @@ describe('UniswapV2', () => {
|
||||
|
||||
const swapAmount = expandTo18Decimals(1)
|
||||
const expectedOutputAmount = bigNumberify('1662497915624478906')
|
||||
|
||||
await token0.transfer(exchange.address, swapAmount)
|
||||
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)
|
||||
})
|
||||
)
|
||||
expect(await exchange.swap)
|
||||
await expect(exchange.connect(wallet).swap(token0.address, wallet.address))
|
||||
.to.emit(exchange, 'Swap')
|
||||
.withArgs(wallet.address, wallet.address, token0.address, swapAmount, expectedOutputAmount)
|
||||
|
||||
@ -135,36 +153,37 @@ 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)))
|
||||
|
||||
// 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)))
|
||||
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)
|
||||
|
||||
const reservesCumulativePre = await exchange.getReservesCumulativeAndOverflows()
|
||||
expect(reservesCumulativePre).to.deep.eq([0, 0, 0, 0].map(n => bigNumberify(n)))
|
||||
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.getReservesCumulativeAndOverflows()
|
||||
const reservesCumulativePost = await exchange.getReservesCumulative()
|
||||
expect(reservesCumulativePost).to.deep.eq([
|
||||
token0Amount.mul(bigNumberify(2)),
|
||||
token1Amount.mul(bigNumberify(2)),
|
||||
0,
|
||||
0
|
||||
bigNumberify(0),
|
||||
bigNumberify(0)
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user