From 4373641a30fe9f4fbddcec1082146d88ffda0b57 Mon Sep 17 00:00:00 2001 From: Danil Kovtonyuk Date: Tue, 16 Nov 2021 03:40:08 +1000 Subject: [PATCH] fix: normalize result values --- package.json | 2 +- src/index.ts | 31 ++++++++++++------------ tests/index.test.ts | 58 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 4c5451b..68e3927 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gas-price-oracle", - "version": "0.4.3", + "version": "0.4.4", "description": "Gas Price Oracle library for Ethereum dApps.", "main": "lib/index.js", "homepage": "https://github.com/peppersec/gas-price-oracle", diff --git a/src/index.ts b/src/index.ts index e28ce51..4100a35 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,6 +36,8 @@ export class GasPriceOracle { Object.assign(this.configuration, options); } + this.configuration.defaultFallbackGasPrices = this.normalize(this.configuration.defaultFallbackGasPrices); + const network = NETWORKS[this.configuration.chainId]; if (network) { @@ -225,38 +227,37 @@ export class GasPriceOracle { : await this.fetchGasPricesOffChain(); return this.lastGasPrice; } catch (e) { - console.log('Failed to fetch gas prices from offchain oracles. Trying onchain ones...'); + console.log('Failed to fetch gas prices from offchain oracles...'); } } if (Object.keys(this.onChainOracles).length > 0) { try { const fastGas = await this.fetchGasPricesOnChain(); - this.lastGasPrice = { - instant: fastGas * 1.3, - fast: fastGas, - standard: fastGas * 0.85, - low: fastGas * 0.5, - }; + this.lastGasPrice = this.categorize(fastGas); return this.lastGasPrice; } catch (e) { - console.log('Failed to fetch gas prices from onchain oracles. Trying from default RPC...'); + console.log('Failed to fetch gas prices from onchain oracles...'); } } try { const fastGas = await this.fetchGasPriceFromRpc(); - this.lastGasPrice = { - instant: fastGas * 1.3, - fast: fastGas, - standard: fastGas * 0.85, - low: fastGas * 0.5, - }; + this.lastGasPrice = this.categorize(fastGas); return this.lastGasPrice; } catch (e) { console.log('Failed to fetch gas prices from default RPC. Last known gas will be returned'); } - return this.lastGasPrice; + return this.normalize(this.lastGasPrice); + } + + categorize(gasPrice: number): GasPrice { + return this.normalize({ + instant: gasPrice * 1.3, + fast: gasPrice, + standard: gasPrice * 0.85, + low: gasPrice * 0.5, + }); } addOffChainOracle(oracle: OffChainOracle): void { diff --git a/tests/index.test.ts b/tests/index.test.ts index d532524..d5e1776 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/no-var-requires */ import chai from 'chai'; import mockery from 'mockery'; +import BigNumber from 'bignumber.js'; import { ChainId, NETWORKS } from '../src/config'; import { GasPriceOracle } from '../src/index'; @@ -240,6 +241,63 @@ describe('fetchMedianGasPriceOffChain', function () { }); }); +describe('normalize result values', function () { + const wrongDecimalsGas = { + instant: 1.1, + fast: 2.12345678901, + standard: 3.12345678901, + low: 3.1234567890123456789, + }; + + const checkDecimals = (gas: GasPrice) => { + const gasPrices: number[] = Object.values(gas); + + for (const gas of gasPrices) { + new BigNumber(gas).dp().should.be.at.most(9); + } + }; + + it('default fallback should be normalized', function () { + mockery.enable({ useCleanCache: true, warnOnUnregistered: false }); + + const { GasPriceOracle } = require('../src/index'); + oracle = new GasPriceOracle({ + defaultFallbackGasPrices: wrongDecimalsGas, + }); + const { configuration } = oracle; + + checkDecimals(configuration.defaultFallbackGasPrices); + + mockery.disable(); + }); + + it('fallback should be normalized', async function () { + mockery.enable({ useCleanCache: true, warnOnUnregistered: false }); + + const { GasPriceOracle } = require('../src/index'); + oracle = new GasPriceOracle(); + + const gas = await oracle.gasPrices(wrongDecimalsGas); + + checkDecimals(gas); + mockery.disable(); + }); + + it('rpc fallback should be normalized', async function () { + const { GasPriceOracle } = require('../src/index'); + oracle = new GasPriceOracle({ chainId: ChainId.ARBITRUM, defaultRpc: 'https://arb1.arbitrum.io/rpc' }); + + const { onChainOracles, offChainOracles } = oracle; + + Object.keys(onChainOracles).forEach(chainOracle => oracle.removeOnChainOracle(chainOracle)); + Object.keys(offChainOracles).forEach(chainOracle => oracle.removeOffChainOracle(chainOracle)); + + const gas = await oracle.gasPrices(); + + checkDecimals(gas); + }); +}); + describe('askOracle', function () { const chains = Object.keys(NETWORKS).map(id => Number(id));