Support token migration (#224)

* Filter transfer event in token swap in Oracle
* Support token swap in monitor
This commit is contained in:
Gerardo Nardelli 2019-11-06 16:49:01 -03:00 committed by Alexander Kolotov
parent f6fa83d7ea
commit 346fa1e732
4 changed files with 63 additions and 6 deletions

@ -17,8 +17,11 @@ const FEE_MANAGER_MODE = {
UNDEFINED: 'UNDEFINED' UNDEFINED: 'UNDEFINED'
} }
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
module.exports = { module.exports = {
BRIDGE_MODES, BRIDGE_MODES,
ERC_TYPES, ERC_TYPES,
FEE_MANAGER_MODE FEE_MANAGER_MODE,
ZERO_ADDRESS
} }

@ -1 +1 @@
Subproject commit 39910b771b1a93a10db829a0b3dddd074c9e1b4e Subproject commit cc7718284d8a35cf74f6ec6847fd7dc7ed1ca885

@ -11,7 +11,8 @@ const {
ERC20_ABI, ERC20_ABI,
ERC677_BRIDGE_TOKEN_ABI, ERC677_BRIDGE_TOKEN_ABI,
getTokenType, getTokenType,
getPastEvents getPastEvents,
ZERO_ADDRESS
} = require('../../commons') } = require('../../commons')
const { normalizeEventInformation } = require('./message') const { normalizeEventInformation } = require('./message')
@ -87,7 +88,7 @@ async function main(mode) {
})).map(normalizeEvent) })).map(normalizeEvent)
if (isExternalErc20) { if (isExternalErc20) {
logger.debug("calling erc20Contract.getPastEvents('Transfer')") logger.debug("calling erc20Contract.getPastEvents('Transfer')")
const transferEvents = (await getPastEvents(erc20Contract, { let transferEvents = (await getPastEvents(erc20Contract, {
event: 'Transfer', event: 'Transfer',
fromBlock: MONITOR_FOREIGN_START_BLOCK, fromBlock: MONITOR_FOREIGN_START_BLOCK,
toBlock: foreignBlockNumber, toBlock: foreignBlockNumber,
@ -96,8 +97,47 @@ async function main(mode) {
} }
})).map(normalizeEvent) })).map(normalizeEvent)
let directTransfers = transferEvents
const tokensSwappedAbiExists = FOREIGN_ABI.filter(e => e.type === 'event' && e.name === 'TokensSwapped')[0]
if (tokensSwappedAbiExists) {
const tokensSwappedEvents = await getPastEvents(foreignBridge, {
event: 'TokensSwapped',
fromBlock: MONITOR_FOREIGN_START_BLOCK,
toBlock: foreignBlockNumber
})
// Get token swap events emitted by foreign bridge
const bridgeTokensSwappedEvents = tokensSwappedEvents.filter(e => e.address === COMMON_FOREIGN_BRIDGE_ADDRESS)
// Get transfer events for each previous erc20
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 previousTransferEvents = (await getPastEvents(previousERC20, {
event: 'Transfer',
fromBlock: MONITOR_FOREIGN_START_BLOCK,
toBlock: foreignBlockNumber,
options: {
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
}
})).map(normalizeEvent)
transferEvents = [...previousTransferEvents, ...transferEvents]
})
)
// filter transfer that is part of a token swap
directTransfers = transferEvents.filter(
e =>
bridgeTokensSwappedEvents.findIndex(
t => t.transactionHash === e.referenceTx && e.recipient === ZERO_ADDRESS
) === -1
)
}
// Get transfer events that didn't have a UserRequestForAffirmation event in the same transaction // Get transfer events that didn't have a UserRequestForAffirmation event in the same transaction
const directTransfers = transferEvents.filter( directTransfers = directTransfers.filter(
e => foreignToHomeRequests.findIndex(t => t.referenceTx === e.referenceTx) === -1 e => foreignToHomeRequests.findIndex(t => t.referenceTx === e.referenceTx) === -1
) )

@ -1,7 +1,7 @@
require('../../../env') require('../../../env')
const promiseLimit = require('promise-limit') const promiseLimit = require('promise-limit')
const { HttpListProviderError } = require('http-list-provider') const { HttpListProviderError } = require('http-list-provider')
const { BRIDGE_VALIDATORS_ABI } = require('../../../../commons') const { BRIDGE_VALIDATORS_ABI, ZERO_ADDRESS } = require('../../../../commons')
const rootLogger = require('../../services/logger') const rootLogger = require('../../services/logger')
const { web3Home, web3Foreign } = require('../../services/web3') const { web3Home, web3Foreign } = require('../../services/web3')
const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = require('../../utils/errors') const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = require('../../utils/errors')
@ -17,7 +17,9 @@ function processTransfersBuilder(config) {
const userRequestForAffirmationAbi = config.foreignBridgeAbi.filter( const userRequestForAffirmationAbi = config.foreignBridgeAbi.filter(
e => e.type === 'event' && e.name === 'UserRequestForAffirmation' e => e.type === 'event' && e.name === 'UserRequestForAffirmation'
)[0] )[0]
const tokensSwappedAbi = config.foreignBridgeAbi.filter(e => e.type === 'event' && e.name === 'TokensSwapped')[0]
const userRequestForAffirmationHash = web3Home.eth.abi.encodeEventSignature(userRequestForAffirmationAbi) const userRequestForAffirmationHash = web3Home.eth.abi.encodeEventSignature(userRequestForAffirmationAbi)
const tokensSwappedHash = tokensSwappedAbi ? web3Home.eth.abi.encodeEventSignature(tokensSwappedAbi) : '0x'
return async function processTransfers(transfers) { return async function processTransfers(transfers) {
const txToSend = [] const txToSend = []
@ -42,6 +44,7 @@ function processTransfersBuilder(config) {
logger.info({ from, value }, `Processing transfer ${transfer.transactionHash}`) logger.info({ from, value }, `Processing transfer ${transfer.transactionHash}`)
const receipt = await web3Foreign.eth.getTransactionReceipt(transfer.transactionHash) const receipt = await web3Foreign.eth.getTransactionReceipt(transfer.transactionHash)
const existsAffirmationEvent = receipt.logs.some( const existsAffirmationEvent = receipt.logs.some(
e => e.address === config.foreignBridgeAddress && e.topics[0] === userRequestForAffirmationHash e => e.address === config.foreignBridgeAddress && e.topics[0] === userRequestForAffirmationHash
) )
@ -55,6 +58,17 @@ function processTransfersBuilder(config) {
return return
} }
const existsTokensSwappedEvent = tokensSwappedAbi
? receipt.logs.some(e => e.address === config.foreignBridgeAddress && e.topics[0] === tokensSwappedHash)
: false
if (from === ZERO_ADDRESS && existsTokensSwappedEvent) {
logger.info(
`Transfer event discarded because token swap is detected in transaction ${transfer.transactionHash}`
)
return
}
let gasEstimate let gasEstimate
try { try {
logger.debug('Estimate gas') logger.debug('Estimate gas')