add more tests
This commit is contained in:
@ -29,4 +29,4 @@ yarn test
|
||||
- [dapp-bin math](https://github.com/ethereum/dapp-bin/pull/50)
|
||||
- [OpenZeppelin ECDSA](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/81b1e4810761b088922dbd19a0642873ea581176/contracts/cryptography/ECDSA.sol)
|
||||
- [OpenZeppelin SafeERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/81b1e4810761b088922dbd19a0642873ea581176/contracts/token/ERC20/SafeERC20.sol)
|
||||
- [DAI token](https://github.com/makerdao/dss/blob/17be7db1c663d8069308c6b78fa5c5f9d71134a3/src/dai.sol)
|
||||
- [DAI](https://github.com/makerdao/dss/blob/17be7db1c663d8069308c6b78fa5c5f9d71134a3/src/dai.sol)
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
pragma solidity 0.5.14;
|
||||
|
||||
import "./interfaces/IUniswapV2.sol";
|
||||
import "./interfaces/IUniswapV2Factory.sol";
|
||||
import "./ERC20.sol";
|
||||
import "./libraries/UQ112x112.sol";
|
||||
import "./libraries/Math.sol";
|
||||
import "./interfaces/IUniswapV2Factory.sol";
|
||||
|
||||
contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0) {
|
||||
using SafeMath for uint;
|
||||
|
||||
@ -3,7 +3,7 @@ import chai from 'chai'
|
||||
import { solidity, createMockProvider, getWallets, deployContract } from 'ethereum-waffle'
|
||||
import { Contract } from 'ethers'
|
||||
import { AddressZero, MaxUint256 } from 'ethers/constants'
|
||||
import { bigNumberify, hexlify } from 'ethers/utils'
|
||||
import { bigNumberify, hexlify, keccak256, defaultAbiCoder, toUtf8Bytes } from 'ethers/utils'
|
||||
import { ecsign } from 'ethereumjs-util'
|
||||
|
||||
import { expandTo18Decimals, getApprovalDigest } from './shared/utilities'
|
||||
@ -35,18 +35,38 @@ describe('ERC20', () => {
|
||||
])
|
||||
})
|
||||
|
||||
it('name, symbol, decimals, totalSupply', async () => {
|
||||
expect(await token.name()).to.eq(TOKEN_DETAILS.name)
|
||||
it('name, symbol, decimals, totalSupply, balanceOf, DOMAIN_SEPARATOR, APPROVE_TYPEHASH', async () => {
|
||||
const name = await token.name()
|
||||
expect(name).to.eq(TOKEN_DETAILS.name)
|
||||
expect(await token.symbol()).to.eq(TOKEN_DETAILS.symbol)
|
||||
expect(await token.decimals()).to.eq(TOKEN_DETAILS.decimals)
|
||||
expect(await token.totalSupply()).to.eq(TOKEN_DETAILS.totalSupply)
|
||||
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply)
|
||||
expect(await token.DOMAIN_SEPARATOR()).to.eq(
|
||||
keccak256(
|
||||
defaultAbiCoder.encode(
|
||||
['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'],
|
||||
[
|
||||
keccak256(
|
||||
toUtf8Bytes('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')
|
||||
),
|
||||
keccak256(toUtf8Bytes(name)),
|
||||
keccak256(toUtf8Bytes('1')),
|
||||
1,
|
||||
token.address
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
expect(await token.APPROVE_TYPEHASH()).to.eq(
|
||||
keccak256(toUtf8Bytes('Approve(address owner,address spender,uint256 value,uint256 nonce,uint256 expiration)'))
|
||||
)
|
||||
})
|
||||
|
||||
it('transfer', async () => {
|
||||
await expect(token.transfer(other.address, TEST_AMOUNT))
|
||||
.to.emit(token, 'Transfer')
|
||||
.withArgs(wallet.address, other.address, TEST_AMOUNT)
|
||||
|
||||
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
|
||||
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT)
|
||||
})
|
||||
@ -55,7 +75,6 @@ describe('ERC20', () => {
|
||||
await expect(token.burn(TEST_AMOUNT))
|
||||
.to.emit(token, 'Transfer')
|
||||
.withArgs(wallet.address, AddressZero, TEST_AMOUNT)
|
||||
|
||||
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
|
||||
expect(await token.totalSupply()).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
|
||||
})
|
||||
@ -64,10 +83,47 @@ describe('ERC20', () => {
|
||||
await expect(token.approve(other.address, TEST_AMOUNT))
|
||||
.to.emit(token, 'Approval')
|
||||
.withArgs(wallet.address, other.address, TEST_AMOUNT)
|
||||
|
||||
expect(await token.allowance(wallet.address, other.address)).to.eq(TEST_AMOUNT)
|
||||
})
|
||||
|
||||
it('transferFrom', async () => {
|
||||
await token.approve(other.address, TEST_AMOUNT)
|
||||
await expect(token.connect(other).transferFrom(wallet.address, other.address, TEST_AMOUNT))
|
||||
.to.emit(token, 'Transfer')
|
||||
.withArgs(wallet.address, other.address, TEST_AMOUNT)
|
||||
expect(await token.allowance(wallet.address, other.address)).to.eq(0)
|
||||
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
|
||||
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT)
|
||||
})
|
||||
|
||||
it('transferFrom:max', async () => {
|
||||
await token.approve(other.address, MaxUint256)
|
||||
await expect(token.connect(other).transferFrom(wallet.address, other.address, TEST_AMOUNT))
|
||||
.to.emit(token, 'Transfer')
|
||||
.withArgs(wallet.address, other.address, TEST_AMOUNT)
|
||||
expect(await token.allowance(wallet.address, other.address)).to.eq(MaxUint256)
|
||||
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
|
||||
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT)
|
||||
})
|
||||
|
||||
it('burnFrom', async () => {
|
||||
await token.approve(other.address, TEST_AMOUNT)
|
||||
await expect(token.connect(other).burnFrom(wallet.address, TEST_AMOUNT))
|
||||
.to.emit(token, 'Transfer')
|
||||
.withArgs(wallet.address, AddressZero, TEST_AMOUNT)
|
||||
expect(await token.allowance(wallet.address, other.address)).to.eq(0)
|
||||
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
|
||||
expect(await token.totalSupply()).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
|
||||
expect(await token.balanceOf(other.address)).to.eq(0)
|
||||
})
|
||||
|
||||
it('transfer:fail', async () => {
|
||||
await expect(token.transfer(other.address, TOKEN_DETAILS.totalSupply.add(1))).to.be.revertedWith(
|
||||
'ds-math-sub-underflow'
|
||||
)
|
||||
await expect(token.connect(other).transfer(wallet.address, 1)).to.be.revertedWith('ds-math-sub-underflow')
|
||||
})
|
||||
|
||||
it('approveMeta', async () => {
|
||||
const nonce = await token.nonces(wallet.address)
|
||||
const expiration = MaxUint256
|
||||
@ -85,38 +141,7 @@ describe('ERC20', () => {
|
||||
)
|
||||
.to.emit(token, 'Approval')
|
||||
.withArgs(wallet.address, other.address, TEST_AMOUNT)
|
||||
|
||||
expect(await token.nonces(wallet.address)).to.eq(bigNumberify(1))
|
||||
expect(await token.allowance(wallet.address, other.address)).to.eq(TEST_AMOUNT)
|
||||
})
|
||||
|
||||
it('transferFrom', async () => {
|
||||
await token.approve(other.address, TEST_AMOUNT)
|
||||
await expect(token.connect(other).transferFrom(wallet.address, other.address, TEST_AMOUNT))
|
||||
.to.emit(token, 'Transfer')
|
||||
.withArgs(wallet.address, other.address, TEST_AMOUNT)
|
||||
|
||||
expect(await token.allowance(wallet.address, other.address)).to.eq(0)
|
||||
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
|
||||
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT)
|
||||
})
|
||||
|
||||
it('burnFrom', async () => {
|
||||
await token.approve(other.address, TEST_AMOUNT)
|
||||
await expect(token.connect(other).burnFrom(wallet.address, TEST_AMOUNT))
|
||||
.to.emit(token, 'Transfer')
|
||||
.withArgs(wallet.address, AddressZero, TEST_AMOUNT)
|
||||
|
||||
expect(await token.allowance(wallet.address, other.address)).to.eq(0)
|
||||
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
|
||||
expect(await token.totalSupply()).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
|
||||
expect(await token.balanceOf(other.address)).to.eq(0)
|
||||
})
|
||||
|
||||
it('transfer:fail', async () => {
|
||||
await expect(token.transfer(other.address, TOKEN_DETAILS.totalSupply.add(1))).to.be.revertedWith(
|
||||
'ds-math-sub-underflow'
|
||||
)
|
||||
await expect(token.connect(other).transfer(wallet.address, 1)).to.be.revertedWith('ds-math-sub-underflow')
|
||||
})
|
||||
})
|
||||
|
||||
@ -61,22 +61,22 @@ describe('UniswapV2', () => {
|
||||
it('mintLiquidity', async () => {
|
||||
const token0Amount = expandTo18Decimals(1)
|
||||
const token1Amount = expandTo18Decimals(4)
|
||||
const expectedLiquidity = expandTo18Decimals(2)
|
||||
|
||||
expect(await exchange.reserve0()).to.eq(bigNumberify(0))
|
||||
expect(await exchange.reserve1()).to.eq(bigNumberify(0))
|
||||
|
||||
await token0.transfer(exchange.address, token0Amount)
|
||||
await token1.transfer(exchange.address, token1Amount)
|
||||
|
||||
const expectedLiquidity = expandTo18Decimals(2)
|
||||
await expect(exchange.connect(wallet).mintLiquidity(wallet.address))
|
||||
.to.emit(exchange, 'LiquidityMinted')
|
||||
.withArgs(wallet.address, token0Amount, token1Amount)
|
||||
.to.emit(exchange, 'Transfer')
|
||||
.withArgs(AddressZero, wallet.address, expectedLiquidity)
|
||||
.to.emit(exchange, 'ReservesUpdated')
|
||||
.withArgs(token0Amount, token1Amount)
|
||||
.to.emit(exchange, 'LiquidityMinted')
|
||||
.withArgs(wallet.address, token0Amount, token1Amount)
|
||||
|
||||
expect(await exchange.totalSupply()).to.eq(expectedLiquidity)
|
||||
expect(await exchange.balanceOf(wallet.address)).to.eq(expectedLiquidity)
|
||||
|
||||
expect(await token0.balanceOf(exchange.address)).to.eq(token0Amount)
|
||||
expect(await token1.balanceOf(exchange.address)).to.eq(token1Amount)
|
||||
expect(await exchange.reserve0()).to.eq(token0Amount)
|
||||
expect(await exchange.reserve1()).to.eq(token1Amount)
|
||||
})
|
||||
@ -87,21 +87,7 @@ 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).swap0(wallet.address)
|
||||
|
||||
await token0.transfer(exchange.address, swapAmount)
|
||||
const gasCost = await exchange.estimate.swap0(wallet.address)
|
||||
console.log(`Gas cost of swap: ${gasCost}`)
|
||||
})
|
||||
|
||||
it('swap', async () => {
|
||||
it('swap0', async () => {
|
||||
const token0Amount = expandTo18Decimals(5)
|
||||
const token1Amount = expandTo18Decimals(10)
|
||||
await addLiquidity(token0Amount, token1Amount)
|
||||
@ -110,41 +96,110 @@ describe('UniswapV2', () => {
|
||||
const expectedOutputAmount = bigNumberify('1662497915624478906')
|
||||
await token0.transfer(exchange.address, swapAmount)
|
||||
await expect(exchange.connect(wallet).swap0(wallet.address))
|
||||
.to.emit(exchange, 'Swap')
|
||||
.withArgs(wallet.address, wallet.address, token0.address, swapAmount, expectedOutputAmount)
|
||||
.to.emit(exchange, 'ReservesUpdated')
|
||||
.withArgs(token0Amount.add(swapAmount), token1Amount.sub(expectedOutputAmount))
|
||||
.to.emit(exchange, 'Swap')
|
||||
.withArgs(wallet.address, wallet.address, token0.address, swapAmount, expectedOutputAmount)
|
||||
|
||||
expect(await exchange.reserve0()).to.eq(token0Amount.add(swapAmount))
|
||||
expect(await exchange.reserve1()).to.eq(token1Amount.sub(expectedOutputAmount))
|
||||
expect(await token0.balanceOf(exchange.address)).to.eq(token0Amount.add(swapAmount))
|
||||
expect(await token1.balanceOf(exchange.address)).to.eq(token1Amount.sub(expectedOutputAmount))
|
||||
|
||||
const totalSupplyToken0 = await token0.totalSupply()
|
||||
const totalSupplyToken1 = await token1.totalSupply()
|
||||
expect(await token0.balanceOf(wallet.address)).to.eq(totalSupplyToken0.sub(token0Amount).sub(swapAmount))
|
||||
expect(await token1.balanceOf(wallet.address)).to.eq(totalSupplyToken1.sub(token1Amount).add(expectedOutputAmount))
|
||||
})
|
||||
|
||||
it('swap1', async () => {
|
||||
const token0Amount = expandTo18Decimals(5)
|
||||
const token1Amount = expandTo18Decimals(10)
|
||||
await addLiquidity(token0Amount, token1Amount)
|
||||
|
||||
const swapAmount = expandTo18Decimals(1)
|
||||
const expectedOutputAmount = bigNumberify('453305446940074565')
|
||||
await token1.transfer(exchange.address, swapAmount)
|
||||
await expect(exchange.connect(wallet).swap1(wallet.address))
|
||||
.to.emit(exchange, 'ReservesUpdated')
|
||||
.withArgs(token0Amount.sub(expectedOutputAmount), token1Amount.add(swapAmount))
|
||||
.to.emit(exchange, 'Swap')
|
||||
.withArgs(wallet.address, wallet.address, token1.address, expectedOutputAmount, swapAmount)
|
||||
|
||||
expect(await exchange.reserve0()).to.eq(token0Amount.sub(expectedOutputAmount))
|
||||
expect(await exchange.reserve1()).to.eq(token1Amount.add(swapAmount))
|
||||
expect(await token0.balanceOf(exchange.address)).to.eq(token0Amount.sub(expectedOutputAmount))
|
||||
expect(await token1.balanceOf(exchange.address)).to.eq(token1Amount.add(swapAmount))
|
||||
const totalSupplyToken0 = await token0.totalSupply()
|
||||
const totalSupplyToken1 = await token1.totalSupply()
|
||||
expect(await token0.balanceOf(wallet.address)).to.eq(totalSupplyToken0.sub(token0Amount).add(expectedOutputAmount))
|
||||
expect(await token1.balanceOf(wallet.address)).to.eq(totalSupplyToken1.sub(token1Amount).sub(swapAmount))
|
||||
})
|
||||
|
||||
it('swap:gas', async () => {
|
||||
const token0Amount = expandTo18Decimals(5)
|
||||
const token1Amount = expandTo18Decimals(10)
|
||||
await addLiquidity(token0Amount, token1Amount)
|
||||
|
||||
// ensure that setting price{0,1}CumulativeLast for the first time doesn't affect our gas math
|
||||
await exchange.connect(wallet).sync()
|
||||
|
||||
const swapAmount = expandTo18Decimals(1)
|
||||
await token0.transfer(exchange.address, swapAmount)
|
||||
const gasCost = await exchange.estimate.swap0(wallet.address)
|
||||
console.log(`Gas required for swap: ${gasCost}`)
|
||||
})
|
||||
|
||||
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)
|
||||
const expectedLiquidity = expandTo18Decimals(3)
|
||||
await exchange.connect(wallet).transfer(exchange.address, expectedLiquidity)
|
||||
// this test is bugged, it catches the token{0,1} transfers before the lp transfers
|
||||
await expect(exchange.connect(wallet).burnLiquidity(wallet.address))
|
||||
// .to.emit(exchange, 'Transfer')
|
||||
// .withArgs(exchange.address, AddressZero, expectedLiquidity)
|
||||
.to.emit(exchange, 'LiquidityBurned')
|
||||
.withArgs(wallet.address, wallet.address, token0Amount, token1Amount)
|
||||
.to.emit(exchange, 'ReservesUpdated')
|
||||
.withArgs(bigNumberify(0), bigNumberify(0))
|
||||
.withArgs(0, 0)
|
||||
|
||||
expect(await exchange.balanceOf(wallet.address)).to.eq(0)
|
||||
expect(await exchange.totalSupply()).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('price{0,1}CumulativeLast', async () => {
|
||||
const token0Amount = expandTo18Decimals(3)
|
||||
const token1Amount = expandTo18Decimals(3)
|
||||
await addLiquidity(token0Amount, token1Amount)
|
||||
|
||||
const blockNumber = await exchange.blockNumberLast()
|
||||
expect(await exchange.price0CumulativeLast()).to.eq(0)
|
||||
expect(await exchange.price1CumulativeLast()).to.eq(0)
|
||||
|
||||
await exchange.connect(wallet).sync()
|
||||
expect(await exchange.price0CumulativeLast()).to.eq(bigNumberify(2).pow(112))
|
||||
expect(await exchange.price1CumulativeLast()).to.eq(bigNumberify(2).pow(112))
|
||||
expect(await exchange.blockNumberLast()).to.eq(blockNumber + 1)
|
||||
|
||||
await exchange.connect(wallet).sync()
|
||||
expect(await exchange.price0CumulativeLast()).to.eq(
|
||||
bigNumberify(2)
|
||||
.pow(112)
|
||||
.mul(2)
|
||||
)
|
||||
expect(await exchange.price1CumulativeLast()).to.eq(
|
||||
bigNumberify(2)
|
||||
.pow(112)
|
||||
.mul(2)
|
||||
)
|
||||
expect(await exchange.blockNumberLast()).to.eq(blockNumber + 2)
|
||||
})
|
||||
})
|
||||
|
||||
@ -19,25 +19,37 @@ const TEST_ADDRESSES = {
|
||||
|
||||
describe('UniswapV2Factory', () => {
|
||||
const provider = createMockProvider(path.join(__dirname, '..', 'waffle.json'))
|
||||
const [wallet] = getWallets(provider)
|
||||
const [wallet, other] = getWallets(provider)
|
||||
const loadFixture = createFixtureLoader(provider, [wallet])
|
||||
|
||||
let bytecode: string
|
||||
let factory: Contract
|
||||
beforeEach(async () => {
|
||||
const { bytecode: _bytecode, factory: _factory } = (await loadFixture(factoryFixture as any)) as FactoryFixture
|
||||
const { bytecode: _bytecode, factory: _factory }: FactoryFixture = await loadFixture(factoryFixture as any)
|
||||
bytecode = _bytecode
|
||||
factory = _factory
|
||||
})
|
||||
|
||||
it('exchangeBytecode', async () => {
|
||||
it('exchangeBytecode, feeAddress, feeOn, exchangesCount', async () => {
|
||||
expect(await factory.exchangeBytecode()).to.eq(bytecode)
|
||||
expect(await factory.feeAddress()).to.eq(wallet.address)
|
||||
expect(await factory.feeOn()).to.eq(false)
|
||||
expect(await factory.exchangesCount()).to.eq(0)
|
||||
})
|
||||
|
||||
it('sortTokens', async () => {
|
||||
expect(await factory.sortTokens(TEST_ADDRESSES.token0, TEST_ADDRESSES.token1)).to.deep.eq([
|
||||
TEST_ADDRESSES.token0,
|
||||
TEST_ADDRESSES.token1
|
||||
])
|
||||
expect(await factory.sortTokens(TEST_ADDRESSES.token1, TEST_ADDRESSES.token0)).to.deep.eq([
|
||||
TEST_ADDRESSES.token0,
|
||||
TEST_ADDRESSES.token1
|
||||
])
|
||||
})
|
||||
|
||||
async function createExchange(tokens: string[]) {
|
||||
const create2Address = getCreate2Address(factory.address, TEST_ADDRESSES.token0, TEST_ADDRESSES.token1, bytecode)
|
||||
|
||||
await expect(factory.createExchange(...tokens))
|
||||
.to.emit(factory, 'ExchangeCreated')
|
||||
.withArgs(TEST_ADDRESSES.token0, TEST_ADDRESSES.token1, create2Address, bigNumberify(1))
|
||||
@ -45,7 +57,6 @@ describe('UniswapV2Factory', () => {
|
||||
await expect(factory.createExchange(...tokens.slice().reverse())).to.be.revertedWith(
|
||||
'UniswapV2Factory: EXCHANGE_EXISTS'
|
||||
)
|
||||
|
||||
expect(await factory.getExchange(...tokens)).to.eq(create2Address)
|
||||
expect(await factory.getExchange(...tokens.slice().reverse())).to.eq(create2Address)
|
||||
expect(await factory.getTokens(create2Address)).to.deep.eq([TEST_ADDRESSES.token0, TEST_ADDRESSES.token1])
|
||||
@ -56,6 +67,7 @@ describe('UniswapV2Factory', () => {
|
||||
expect(await exchange.factory()).to.eq(factory.address)
|
||||
expect(await exchange.token0()).to.eq(TEST_ADDRESSES.token0)
|
||||
expect(await exchange.token1()).to.eq(TEST_ADDRESSES.token1)
|
||||
expect(await exchange.feeAddress()).to.eq(wallet.address)
|
||||
}
|
||||
|
||||
it('createExchange', async () => {
|
||||
@ -65,4 +77,17 @@ describe('UniswapV2Factory', () => {
|
||||
it('createExchange:reverse', async () => {
|
||||
await createExchange([TEST_ADDRESSES.token1, TEST_ADDRESSES.token0])
|
||||
})
|
||||
|
||||
it('setFeeAddress', async () => {
|
||||
await expect(factory.connect(other).setFeeAddress(other.address)).to.be.revertedWith('UniswapV2Factory: FORBIDDEN')
|
||||
await factory.setFeeAddress(other.address)
|
||||
expect(await factory.feeAddress()).to.eq(other.address)
|
||||
await expect(factory.setFeeAddress(wallet.address)).to.be.revertedWith('UniswapV2Factory: FORBIDDEN')
|
||||
})
|
||||
|
||||
it('turnFeeOn', async () => {
|
||||
await expect(factory.connect(other).turnFeeOn()).to.be.revertedWith('UniswapV2Factory: FORBIDDEN')
|
||||
await factory.turnFeeOn()
|
||||
expect(await factory.feeOn()).to.eq(true)
|
||||
})
|
||||
})
|
||||
|
||||
@ -15,10 +15,9 @@ export interface FactoryFixture {
|
||||
|
||||
export async function factoryFixture(provider: providers.Web3Provider, [wallet]: Wallet[]): Promise<FactoryFixture> {
|
||||
const bytecode = `0x${UniswapV2.evm.bytecode.object}`
|
||||
const factory = await deployContract(wallet, UniswapV2Factory, [bytecode, AddressZero], {
|
||||
const factory = await deployContract(wallet, UniswapV2Factory, [bytecode, wallet.address], {
|
||||
gasLimit: (provider._web3Provider as any).options.gasLimit
|
||||
})
|
||||
|
||||
return { bytecode, factory }
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,10 @@ import {
|
||||
solidityPack
|
||||
} from 'ethers/utils'
|
||||
|
||||
export function expandTo18Decimals(n: number): BigNumber {
|
||||
return bigNumberify(n).mul(bigNumberify(10).pow(18))
|
||||
}
|
||||
|
||||
const APPROVE_TYPEHASH = keccak256(
|
||||
toUtf8Bytes('Approve(address owner,address spender,uint256 value,uint256 nonce,uint256 expiration)')
|
||||
)
|
||||
@ -29,8 +33,22 @@ const GET_DOMAIN_SEPARATOR = async (token: Contract) => {
|
||||
)
|
||||
}
|
||||
|
||||
export function expandTo18Decimals(n: number): BigNumber {
|
||||
return bigNumberify(n).mul(bigNumberify(10).pow(18))
|
||||
export function getCreate2Address(
|
||||
factoryAddress: string,
|
||||
token0Address: string,
|
||||
token1Address: string,
|
||||
bytecode: string
|
||||
): string {
|
||||
const create2Inputs = [
|
||||
'0xff',
|
||||
factoryAddress,
|
||||
keccak256(solidityPack(['address', 'address'], [token0Address, token1Address])),
|
||||
keccak256(bytecode)
|
||||
]
|
||||
|
||||
const sanitizedInputs = `0x${create2Inputs.map(i => i.slice(2)).join('')}`
|
||||
|
||||
return getAddress(`0x${keccak256(sanitizedInputs).slice(-40)}`)
|
||||
}
|
||||
|
||||
interface Approve {
|
||||
@ -38,7 +56,6 @@ interface Approve {
|
||||
spender: string
|
||||
value: BigNumber
|
||||
}
|
||||
|
||||
export async function getApprovalDigest(
|
||||
token: Contract,
|
||||
approve: Approve,
|
||||
@ -64,24 +81,6 @@ export async function getApprovalDigest(
|
||||
)
|
||||
}
|
||||
|
||||
export function getCreate2Address(
|
||||
factoryAddress: string,
|
||||
token0Address: string,
|
||||
token1Address: string,
|
||||
bytecode: string
|
||||
): string {
|
||||
const create2Inputs = [
|
||||
'0xff',
|
||||
factoryAddress,
|
||||
keccak256(solidityPack(['address', 'address'], [token0Address, token1Address])),
|
||||
keccak256(bytecode)
|
||||
]
|
||||
|
||||
const sanitizedInputs = `0x${create2Inputs.map(i => i.slice(2)).join('')}`
|
||||
|
||||
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)(
|
||||
|
||||
Reference in New Issue
Block a user