import { expect } from 'chai' ; import { OptionsFactoryInstance , MockCompoundOracleInstance } from '../build/types/truffle-types' ; const Web3Utils = require ( 'web3-utils' ) ; const OptionsFactory = artifacts . require ( 'OptionsFactory' ) ; const MockCompoundOracle = artifacts . require ( 'MockCompoundOracle' ) ; const MockUniswapFactory = artifacts . require ( 'MockUniswapFactory' ) ; const OptionsContract = artifacts . require ( 'OptionsContract' ) ; const truffleAssert = require ( 'truffle-assertions' ) ; import { getUnixTime , addMonths , addSeconds , fromUnixTime } from 'date-fns' ; const { expectRevert , time } = require ( '@openzeppelin/test-helpers' ) ; contract ( 'OptionsFactory' , accounts => { const creatorAddress = accounts [ 0 ] ; const firstOwnerAddress = accounts [ 1 ] ; let optionsFactory ; let compoundOracle ; const now = Date . now ( ) ; const expiry = getUnixTime ( addMonths ( now , 3 ) ) ; const windowSize = expiry ; before ( async ( ) => { optionsFactory = await OptionsFactory . deployed ( ) ; compoundOracle = await MockCompoundOracle . deployed ( ) ; optionsFactory = await OptionsFactory . deployed ( ) ; } ) ; describe ( '#addAsset()' , ( ) => { it ( 'should add an asset correctly' , async ( ) => { const result = await optionsFactory . addAsset ( 'DAI' , '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359' ) ; truffleAssert . eventEmitted ( result , 'AssetAdded' , ( ev ) => { return ( ev . asset === Web3Utils . keccak256 ( 'DAI' ) && ev . addr === '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359' ) ; } ) ; const supported = await optionsFactory . supportsAsset ( 'DAI' ) ; expect ( supported ) . to . be . true ; } ) ; it ( 'should not add ETH' , async ( ) => { try { const result = await optionsFactory . addAsset ( 'ETH' , '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359' ) ; } catch ( err ) { return ; } truffleAssert . fails ( 'should throw error' ) ; } ) ; it ( 'fails if anyone but owner tries to add asset' , async ( ) => { try { await optionsFactory . addAsset ( 'BAT' , '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359' , { from : firstOwnerAddress } ) ; } catch ( err ) { return ; } truffleAssert . fails ( 'should throw error' ) ; } ) ; it ( 'fails if an asset is added twice' , async ( ) => { try { await optionsFactory . addAsset ( 'DAI' , '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359' ) ; } catch ( err ) { return ; } truffleAssert . fails ( 'should throw error' ) ; } ) ; it ( 'should add a second asset correctly' , async ( ) => { const result = await optionsFactory . addAsset ( 'BAT' , '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359' ) ; truffleAssert . eventEmitted ( result , 'AssetAdded' , ( ev ) => { return ( ev . asset === Web3Utils . keccak256 ( 'BAT' ) && ev . addr === '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359' ) ; } ) ; const supported = await optionsFactory . supportsAsset ( 'BAT' ) ; expect ( supported ) . to . be . true ; } ) ; } ) ; describe ( '#changeAsset()' , ( ) => { it ( 'should change an asset that exists correctly' , async ( ) => { const result = await optionsFactory . changeAsset ( 'BAT' , '0xEd1af8c036fcAEbc5be8FcbF4a85d08F67Ce5Fa1' ) ; truffleAssert . eventEmitted ( result , 'AssetChanged' , ( ev ) => { return ( ev . asset === Web3Utils . keccak256 ( 'BAT' ) && ev . addr === '0xEd1af8c036fcAEbc5be8FcbF4a85d08F67Ce5Fa1' ) ; } ) ; } ) ; it ( "fails if asset doesn't exist" , async ( ) => { try { const result = await optionsFactory . changeAsset ( 'ZRX' , '0xEd1af8c036fcAEbc5be8FcbF4a85d08F67Ce5Fa1' ) ; } catch ( err ) { return ; } truffleAssert . fails ( 'should throw error' ) ; } ) ; it ( 'fails if anyone but owner tries to change asset' , async ( ) => { try { await optionsFactory . changeAsset ( 'BAT' , '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359' , { from : firstOwnerAddress } ) ; } catch ( err ) { return ; } truffleAssert . fails ( 'should throw error' ) ; } ) ; } ) ; describe ( '#deleteAsset()' , ( ) => { it ( 'should delete an asset that exists correctly' , async ( ) => { const result = await optionsFactory . deleteAsset ( 'BAT' ) ; truffleAssert . eventEmitted ( result , 'AssetDeleted' , ( ev ) => { return ev . asset === Web3Utils . keccak256 ( 'BAT' ) ; } ) ; } ) ; it ( "fails if asset doesn't exist" , async ( ) => { try { const result = await optionsFactory . deleteAsset ( 'ZRX' ) ; } catch ( err ) { return ; } truffleAssert . fails ( 'should throw error' ) ; } ) ; it ( 'fails if anyone but owner tries to delete asset' , async ( ) => { try { await optionsFactory . deleteAsset ( 'BAT' , { from : firstOwnerAddress } ) ; } catch ( err ) { return ; } truffleAssert . fails ( 'should throw error' ) ; } ) ; } ) ; describe ( '#createOptionsContract()' , ( ) => { it ( 'should not allow to create an expired new options contract' , async ( ) => { const expiredExpiry = '1579111873' ; await expectRevert ( optionsFactory . createOptionsContract ( 'ETH' , - '18' , 'ETH' , - '18' , - '17' , '90' , - '18' , 'ETH' , expiredExpiry , expiredExpiry , { from : creatorAddress , gas : '4000000' } ) , 'Cannot create an expired option' ) ; } ) ; it ( 'should not allow to create a new options contract where windowSize is bigger than expiry' , async ( ) => { const bigWindowSize = getUnixTime ( addSeconds ( fromUnixTime ( expiry ) , 1 ) ) ; await expectRevert ( optionsFactory . createOptionsContract ( 'ETH' , - '18' , 'ETH' , - '18' , - '17' , '90' , - '18' , 'ETH' , expiry , bigWindowSize , { from : creatorAddress , gas : '4000000' } ) , 'Invalid _windowSize' ) ; } ) ; it ( 'should create a new options contract correctly' , async ( ) => { const result = await optionsFactory . createOptionsContract ( 'ETH' , - '18' , 'ETH' , - '18' , - '17' , '90' , - '18' , 'ETH' , expiry , windowSize , { from : creatorAddress , gas : '4000000' } ) ; const index = ( await optionsFactory . getNumberOfOptionsContracts ( ) ) . toNumber ( ) ; const lastAdded = await optionsFactory . optionsContracts ( index - 1 ) ; truffleAssert . eventEmitted ( result , 'OptionsContractCreated' , ( ev ) => { return ev . addr === lastAdded ; } ) ; } ) ; it ( 'anyone else should be able to create a second options contract correctly' , async ( ) => { const result = await optionsFactory . createOptionsContract ( 'ETH' , - '18' , 'ETH' , - '18' , - '17' , '90' , - '18' , 'ETH' , expiry , windowSize , { from : firstOwnerAddress , gas : '4000000' } ) ; const index = ( await optionsFactory . getNumberOfOptionsContracts ( ) ) . toNumber ( ) ; const lastAdded = await optionsFactory . optionsContracts ( index - 1 ) ; truffleAssert . eventEmitted ( result , 'OptionsContractCreated' , ( ev ) => { return ev . addr === lastAdded ; } ) ; const ownerFactory = await optionsFactory . owner ( ) ; expect ( ownerFactory ) . to . equal ( creatorAddress ) ; const optionsContractAddr = result . logs [ 1 ] . args [ 0 ] ; const optionContract = await OptionsContract . at ( optionsContractAddr ) ; const optionContractOwner = await optionContract . owner ( ) ; expect ( optionContractOwner ) . to . equal ( creatorAddress ) ; } ) ; } ) ; } ) ;