From ef0a7346509ad0b953be261dfe43319f6a4605ad Mon Sep 17 00:00:00 2001 From: Gerardo Nardelli Date: Thu, 19 Dec 2019 06:39:41 -0300 Subject: [PATCH] Support two tokens deposits in monitor (#245) * Support two tokens deposits in monitor * update chrome version --- .circleci/config.yml | 2 +- contracts | 2 +- monitor/getBalances.js | 50 +++++++++++++++++++++++++++++++++---- monitor/utils/events.js | 18 ++++++++++--- monitor/utils/tokenUtils.js | 40 +++++++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 monitor/utils/tokenUtils.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 88c5aa0c..a0ddf53c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,7 +14,7 @@ orbs: - run: name: Install Chrome command: | - wget -O chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb + wget -O chrome.deb https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_77.0.3865.120-1_amd64.deb sudo dpkg -i chrome.deb install-node: steps: diff --git a/contracts b/contracts index 055bcb62..c8e0f48b 160000 --- a/contracts +++ b/contracts @@ -1 +1 @@ -Subproject commit 055bcb62a794ed913dfec10b6558e3b57a314151 +Subproject commit c8e0f48bdfd06e96154bb323b20fc9de38cb9c3e diff --git a/monitor/getBalances.js b/monitor/getBalances.js index e7fcf899..289787fe 100644 --- a/monitor/getBalances.js +++ b/monitor/getBalances.js @@ -83,6 +83,26 @@ async function main(bridgeMode) { const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS) const erc20Address = await foreignBridge.methods.erc20token().call() const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address) + let foreignHalfDuplexErc20Balance = 0 + let displayHalfDuplexToken = false + let tokenSwapAllowed = false + try { + const halfDuplexTokenAddress = await foreignBridge.methods.halfDuplexErc20token().call() + if (halfDuplexTokenAddress !== erc20Address) { + const halfDuplexToken = new web3Foreign.eth.Contract(ERC20_ABI, halfDuplexTokenAddress) + logger.debug('calling halfDuplexToken.methods.balanceOf') + foreignHalfDuplexErc20Balance = await halfDuplexToken.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call() + logger.debug('getting last block numbers') + const block = await web3Foreign.eth.getBlock('latest') + + logger.debug(`Checking if SCD Emergency Shutdown has happened`) + tokenSwapAllowed = await foreignBridge.methods.isTokenSwapAllowed(block.timestamp).call() + displayHalfDuplexToken = true + } + } catch (e) { + logger.debug('Methods for half duplex token are not present') + } + logger.debug('calling erc20Contract.methods.balanceOf') const foreignErc20Balance = await erc20Contract.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call() @@ -91,7 +111,7 @@ async function main(bridgeMode) { const blockRewardAddress = await homeBridge.methods.blockRewardContract().call() const blockRewardContract = new web3Home.eth.Contract(BLOCK_REWARD_ABI, blockRewardAddress) logger.debug('calling blockReward.methods.mintedTotally') - const mintedCoins = await blockRewardContract.methods.mintedTotally().call() + const mintedCoins = await blockRewardContract.methods.mintedTotallyByBridge(COMMON_HOME_BRIDGE_ADDRESS).call() logger.debug('calling homeBridge.methods.totalBurntCoins') const burntCoins = await homeBridge.methods.totalBurntCoins().call() @@ -99,16 +119,36 @@ async function main(bridgeMode) { const burntCoinsBN = new BN(burntCoins) const totalSupplyBN = mintedCoinsBN.minus(burntCoinsBN) const foreignErc20BalanceBN = new BN(foreignErc20Balance) + const halfDuplexErc20BalanceBN = + displayHalfDuplexToken && tokenSwapAllowed ? new BN(foreignHalfDuplexErc20Balance) : new BN(0) + + const diff = foreignErc20BalanceBN + .plus(halfDuplexErc20BalanceBN) + .minus(totalSupplyBN) + .toFixed() + + let foreign = { + erc20Balance: Web3Utils.fromWei(foreignErc20Balance) + } + + if (displayHalfDuplexToken && tokenSwapAllowed) { + foreign = { + ...foreign, + halfDuplexErc20Balance: Web3Utils.fromWei(foreignHalfDuplexErc20Balance) + } + } else if (displayHalfDuplexToken && !tokenSwapAllowed) { + foreign = { + ...foreign, + halfDuplexErc20BalanceAfterES: Web3Utils.fromWei(foreignHalfDuplexErc20Balance) + } + } - const diff = foreignErc20BalanceBN.minus(totalSupplyBN).toFixed() logger.debug('Done') return { home: { totalSupply: Web3Utils.fromWei(totalSupplyBN.toFixed()) }, - foreign: { - erc20Balance: Web3Utils.fromWei(foreignErc20Balance) - }, + foreign, balanceDiff: Number(Web3Utils.fromWei(diff)), lastChecked: Math.floor(Date.now() / 1000) } diff --git a/monitor/utils/events.js b/monitor/utils/events.js index d71454ea..57d89149 100644 --- a/monitor/utils/events.js +++ b/monitor/utils/events.js @@ -15,6 +15,7 @@ const { ZERO_ADDRESS } = require('../../commons') const { normalizeEventInformation } = require('./message') +const { filterTransferBeforeES } = require('./tokenUtils') const { COMMON_HOME_RPC_URL, @@ -42,10 +43,11 @@ async function main(mode) { const v1Bridge = bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC_V1 let isExternalErc20 let erc20Contract + let erc20Address let normalizeEvent = normalizeEventInformation if (bridgeMode !== BRIDGE_MODES.ARBITRARY_MESSAGE) { const erc20MethodName = bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC || v1Bridge ? 'erc677token' : 'erc20token' - const erc20Address = await foreignBridge.methods[erc20MethodName]().call() + erc20Address = await foreignBridge.methods[erc20MethodName]().call() const tokenType = await getTokenType( new web3Foreign.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, erc20Address), COMMON_FOREIGN_BRIDGE_ADDRESS @@ -113,9 +115,9 @@ async function main(mode) { const uniqueTokenAddresses = [...new Set(bridgeTokensSwappedEvents.map(e => e.returnValues.from))] await Promise.all( uniqueTokenAddresses.map(async tokenAddress => { - const previousERC20 = new web3Foreign.eth.Contract(ERC20_ABI, tokenAddress) + const halfDuplexTokenContract = new web3Foreign.eth.Contract(ERC20_ABI, tokenAddress) - const previousTransferEvents = (await getPastEvents(previousERC20, { + const halfDuplexTransferEvents = (await getPastEvents(halfDuplexTokenContract, { event: 'Transfer', fromBlock: MONITOR_FOREIGN_START_BLOCK, toBlock: foreignBlockNumber, @@ -123,7 +125,15 @@ async function main(mode) { filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS } } })).map(normalizeEvent) - transferEvents = [...previousTransferEvents, ...transferEvents] + + // Remove events after the ES + const validHalfDuplexTransfers = await filterTransferBeforeES( + halfDuplexTransferEvents, + web3Foreign, + foreignBridge + ) + + transferEvents = [...validHalfDuplexTransfers, ...transferEvents] }) ) diff --git a/monitor/utils/tokenUtils.js b/monitor/utils/tokenUtils.js new file mode 100644 index 00000000..d5783202 --- /dev/null +++ b/monitor/utils/tokenUtils.js @@ -0,0 +1,40 @@ +let beforeESBiggestBlockNumber = 0 + +/** + * + * Returns true if the event was before the Emergency Shutdown. + * The method has an optimization to avoid making request if a bigger block number is confirmed + * to be before the ES. Events should be iterated from newer to older order to use the optimization. + */ +async function transferBeforeES(event, web3Foreign, foreignBridge) { + const { blockNumber } = event + + if (blockNumber < beforeESBiggestBlockNumber) { + return true + } + + const block = await web3Foreign.eth.getBlock(blockNumber) + + const tokenSwapAllowed = await foreignBridge.methods.isTokenSwapAllowed(block.timestamp).call() + if (tokenSwapAllowed) { + beforeESBiggestBlockNumber = blockNumber + } + return tokenSwapAllowed +} + +async function filterTransferBeforeES(array, web3Foreign, foreignBridge) { + const newArray = [] + // Iterate events from newer to older + for (let i = array.length - 1; i >= 0; i--) { + const beforeES = await transferBeforeES(array[i], web3Foreign, foreignBridge) + if (beforeES) { + // add element to first position so the new array will have the same order + newArray.unshift(array[i]) + } + } + return newArray +} + +module.exports = { + filterTransferBeforeES +}