import chai , { expect } from 'chai' ; import { Contract } from 'ethers' ; import { AddressZero } from 'ethers/constants' ; import { bigNumberify } from 'ethers/utils' ; import { solidity , MockProvider , createFixtureLoader } from 'ethereum-waffle' ; import { getCreate2Address } from './shared/utilities' ; import { factoryFixture } from './shared/fixtures' ; import PancakePair from '../build/PancakePair.json' ; chai . use ( solidity ) ; const TEST_ADDRESSES = [ '0x1000000000000000000000000000000000000000' , '0x2000000000000000000000000000000000000000' ] ; describe ( 'PancakeFactory' , ( ) => { const provider = new MockProvider ( { hardfork : 'istanbul' , mnemonic : 'horn horn horn horn horn horn horn horn horn horn horn horn' , gasLimit : 9999999 } ) ; const [ wallet , other ] = provider . getWallets ( ) ; const loadFixture = createFixtureLoader ( provider , [ wallet , other ] ) ; let factory ; beforeEach ( async ( ) => { const fixture = await loadFixture ( factoryFixture ) ; factory = fixture . factory ; } ) ; it ( 'feeTo, feeToSetter, allPairsLength' , async ( ) => { expect ( await factory . feeTo ( ) ) . to . eq ( AddressZero ) ; expect ( await factory . feeToSetter ( ) ) . to . eq ( wallet . address ) ; expect ( await factory . allPairsLength ( ) ) . to . eq ( 0 ) ; } ) ; async function createPair ( tokens ) { const bytecode = `0x${ PancakePair . evm . bytecode . object }` ; const create2Address = getCreate2Address ( factory . address , tokens , bytecode ) ; await expect ( factory . createPair ( ... tokens ) ) . to . emit ( factory , 'PairCreated' ) . withArgs ( TEST_ADDRESSES [ 0 ] , TEST_ADDRESSES [ 1 ] , create2Address , bigNumberify ( 1 ) ) ; await expect ( factory . createPair ( ... tokens ) ) . to . be . reverted ; await expect ( factory . createPair ( ... tokens . slice ( ) . reverse ( ) ) ) . to . be . reverted ; expect ( await factory . getPair ( ... tokens ) ) . to . eq ( create2Address ) ; expect ( await factory . getPair ( ... tokens . slice ( ) . reverse ( ) ) ) . to . eq ( create2Address ) ; expect ( await factory . allPairs ( 0 ) ) . to . eq ( create2Address ) ; expect ( await factory . allPairsLength ( ) ) . to . eq ( 1 ) ; const pair = new Contract ( create2Address , JSON . stringify ( PancakePair . abi ) , provider ) ; expect ( await pair . factory ( ) ) . to . eq ( factory . address ) ; expect ( await pair . token0 ( ) ) . to . eq ( TEST_ADDRESSES [ 0 ] ) ; expect ( await pair . token1 ( ) ) . to . eq ( TEST_ADDRESSES [ 1 ] ) ; } it ( 'createPair' , async ( ) => { await createPair ( TEST_ADDRESSES ) ; } ) ; it ( 'createPair:reverse' , async ( ) => { await createPair ( TEST_ADDRESSES . slice ( ) . reverse ( ) as [ string , string ] ) ; } ) ; it ( 'createPair:gas' , async ( ) => { const tx = await factory . createPair ( ... TEST_ADDRESSES ) ; const receipt = await tx . wait ( ) ; expect ( receipt . gasUsed ) . to . eq ( 2509120 ) ; } ) ; it ( 'setFeeTo' , async ( ) => { await expect ( factory . connect ( other ) . setFeeTo ( other . address ) ) . to . be . revertedWith ( 'Pancake: FORBIDDEN' ) ; await factory . setFeeTo ( wallet . address ) ; expect ( await factory . feeTo ( ) ) . to . eq ( wallet . address ) ; } ) ; it ( 'setFeeToSetter' , async ( ) => { await expect ( factory . connect ( other ) . setFeeToSetter ( other . address ) ) . to . be . revertedWith ( 'Pancake: FORBIDDEN' ) ; await factory . setFeeToSetter ( other . address ) ; expect ( await factory . feeToSetter ( ) ) . to . eq ( other . address ) ; await expect ( factory . setFeeToSetter ( wallet . address ) ) . to . be . revertedWith ( 'Pancake: FORBIDDEN' ) ; } ) ; } ) ;