import Web3 from 'web3' ; import { Contract } from 'web3-eth-contract' ; import { AbiItem } from 'web3-utils' ; import PriceOracleABI from '../../contracts/abi/v0.8.7/price-oracle' ; import ExchangeABI from '../../contracts/abi/v0.8.7/exchange' ; import { getOracle , getAddress } from '../../contracts/addresses' ; import BN from 'bn.js' ; import { safeFloatConvert } from '../utils/general-utils' ; const tokenDecimals = new BN ( '18' ) ; const ten = new BN ( '10' ) ; export default class LayerTwoOracle { constructor ( private layer2Web3 ) { } async convertToSpend ( token , amount ) { let exchange = new this . layer2Web3 . eth . Contract ( ExchangeABI as AbiItem [ ] , await getAddress ( 'exchange' , this . layer2Web3 ) ) ; let spendAmount = await exchange . methods . convertToSpend ( token , amount ) . call ( ) ; return Number ( spendAmount ) ; } async convertFromSpend ( token , amount ) { let exchange = new this . layer2Web3 . eth . Contract ( ExchangeABI as AbiItem [ ] , await getAddress ( 'exchange' , this . layer2Web3 ) ) ; return await exchange . methods . convertFromSpend ( token , amount . toString ( ) ) . call ( ) ; } async getRateLock ( tokenAddress ) { let exchange = new this . layer2Web3 . eth . Contract ( ExchangeABI as AbiItem [ ] , await getAddress ( 'exchange' , this . layer2Web3 ) ) ; let { price } = await exchange . methods . exchangeRateOf ( tokenAddress ) . call ( ) ; return price ; } async getUSDConverter ( token ) { const oracle = await this . getOracleContract ( token ) ; const usdRawRate = new BN ( ( await oracle . methods . usdPrice ( ) . call ( ) ) . price ) ; const oracleDecimals = Number ( await oracle . methods . decimals ( ) . call ( ) ) ; return ( amountInWei ) => { let rawAmount = usdRawRate . mul ( new BN ( amountInWei ) ) . div ( ten . pow ( tokenDecimals ) ) ; return safeFloatConvert ( rawAmount , oracleDecimals ) ; } ; } async getUSDPrice ( token , amount ) { let oracle = await this . getOracleContract ( token ) ; let usdRawRate = new BN ( ( await oracle . methods . usdPrice ( ) . call ( ) ) . price ) ; let oracleDecimals = Number ( await oracle . methods . decimals ( ) . call ( ) ) ; let rawAmount = usdRawRate . mul ( new BN ( amount ) ) . div ( ten . pow ( tokenDecimals ) ) ; return safeFloatConvert ( rawAmount , oracleDecimals ) ; } async getETHPrice ( token , amount ) { let oracle = await this . getOracleContract ( token ) ; let ethRawRate = new BN ( ( await oracle . methods . ethPrice ( ) . call ( ) ) . price ) ; let oracleDecimals = new BN ( await oracle . methods . decimals ( ) . call ( ) ) ; let weiAmount = ethRawRate . mul ( new BN ( amount ) ) . div ( ten . pow ( oracleDecimals ) ) ; return weiAmount . toString ( ) ; } async getUpdatedAt ( token ) { let oracle = await this . getOracleContract ( token ) ; let unixTime = Number ( ( await oracle . methods . usdPrice ( ) . call ( ) ) . updatedAt ) ; return new Date ( unixTime * 1000 ) ; } private async getOracleContract ( token ) { let address = await getOracle ( token , this . layer2Web3 ) ; return new this . layer2Web3 . eth . Contract ( PriceOracleABI as AbiItem [ ] , address ) ; } }