text: 'use strict';
  
  const Web3 = require('web3');
  const axios = require('axios');
  const { gray, yellow, red, cyan } = require('chalk');
  
  const { loadConnections } = require('./util');
  const { toBytes32 } = require('../../.');
  
  module.exports = async ({ network, useOvm, providerUrl, pynths, oldExrates, standaloneFeeds }) => {
  	const output = [];
  	const { etherscanUrl } = loadConnections({ network });
  
  	const web3 = new Web3(new Web3.providers.HttpProvider(providerUrl));
  
  	const feeds = standaloneFeeds.concat(pynths);
  
  	let abi;
  
  	for (const { name, asset, feed, inverted } of feeds) {
  		const currencyKey = name || asset; // either name of pynth or asset for standalone
  		if (feed) {
  			if (!web3.utils.isAddress(feed)) {
  				throw Error(
  					`Invalid aggregator address for ${currencyKey}: ${feed}. (If mixed case, make sure it is valid checksum)`
  				);
  			}
  
  			if (!abi) {
  				if (useOvm) {
  					abi = require('@chainlink/contracts-0.0.10/abi/v0.5/AggregatorV2V3Interface.json')
  						.compilerOutput.abi;
  				} else {
  					// Get the ABI from the first aggregator on Etherscan
  					// Note: assumes all use the same ABI
  					const {
  						data: { result },
  					} = await axios.get(etherscanUrl, {
  						params: {
  							module: 'contract',
  							action: 'getabi',
  							address: feed,
  							apikey: ['mumbai', 'polygon'].includes(network)
  								? process.env.POLYGONSCAN_KEY
  								: ['bsc', 'bsctest'].includes(network)
  								? process.env.BSCSCAN_KEY
  								: ['moonbase-alphanet'].includes(network)
  								? process.env.SUBSCAN_KEY
  								: process.env.ETHERSCAN_KEY,
  						},
  					});
  					abi = JSON.parse(result);
  				}
  			}
  
  			const liveAggregator = new web3.eth.Contract(abi, feed);
  
  			const [
  				aggAnswerRaw,
  				exRatesAnswerRaw,
  				{ frozenAtUpperLimit, frozenAtLowerLimit },
  			] = await Promise.all([
  				liveAggregator.methods.latestAnswer().call(),
  				oldExrates.methods.rateForCurrency(toBytes32(currencyKey)).call(),
  				oldExrates.methods.inversePricing(toBytes32(currencyKey)).call(),
  			]);
  
  			let answer = (aggAnswerRaw / 1e8).toString();
  
  			// do a quick calculation of he inverted number
  			if (inverted) {
  				answer = 2 * inverted.entryPoint - answer;
  				answer = frozenAtLowerLimit ? inverted.lowerLimit : Math.max(answer, inverted.lowerLimit);
  				answer = frozenAtUpperLimit ? inverted.upperLimit : Math.min(answer, inverted.upperLimit);
  			}
  
  			const existing = web3.utils.fromWei(exRatesAnswerRaw);
  
  			if (answer === existing) {
  				output.push(
  					gray(
  						`- ${
  							name ? 'Pynth ' : ''
  						}${currencyKey} aggregated price: ${answer} (same as currently on-chain)`
  					)
  				);
  			} else {
  				const diff = ((Math.abs(answer - existing) / answer) * 100).toFixed(2);
  
  				const colorize = diff > 5 ? red : diff > 1 ? yellow : cyan;
  				output.push(
  					colorize(
  						`- ${
  							name ? 'Pynth ' : ''
  						}${currencyKey} aggregated price: ${answer} vs ${existing} (${diff} %)`
  					)
  				);
  			}
  		}
  	}
  
  	return output;
  };
  