2019-05-06 14:12:53 +03:00
|
|
|
const Web3 = require('web3')
|
|
|
|
const assert = require('assert')
|
2019-07-02 16:12:57 +03:00
|
|
|
const {
|
|
|
|
user,
|
|
|
|
validator,
|
2020-01-20 23:00:04 +03:00
|
|
|
secondValidator,
|
|
|
|
thirdValidator,
|
2019-07-02 16:12:57 +03:00
|
|
|
nativeToErcBridge,
|
|
|
|
secondUser,
|
2020-01-20 23:00:04 +03:00
|
|
|
thirdUser,
|
|
|
|
fourthUser,
|
2019-07-02 16:12:57 +03:00
|
|
|
homeRPC,
|
|
|
|
foreignRPC
|
|
|
|
} = require('../../e2e-commons/constants.json')
|
2020-01-20 23:00:04 +03:00
|
|
|
const { ERC677_BRIDGE_TOKEN_ABI, HOME_NATIVE_TO_ERC_ABI, FOREIGN_NATIVE_TO_ERC_ABI } = require('../../commons')
|
2020-02-11 20:50:34 +03:00
|
|
|
const { uniformRetry, sleep } = require('../../e2e-commons/utils')
|
2020-01-20 23:00:04 +03:00
|
|
|
const { setRequiredSignatures } = require('./utils')
|
2019-05-06 14:12:53 +03:00
|
|
|
|
2019-06-04 15:02:45 +03:00
|
|
|
const homeWeb3 = new Web3(new Web3.providers.HttpProvider(homeRPC.URL))
|
|
|
|
const foreignWeb3 = new Web3(new Web3.providers.HttpProvider(foreignRPC.URL))
|
|
|
|
const { toBN } = foreignWeb3.utils
|
2019-05-06 14:12:53 +03:00
|
|
|
|
2019-09-13 10:11:38 +03:00
|
|
|
const COMMON_HOME_BRIDGE_ADDRESS = nativeToErcBridge.home
|
|
|
|
const COMMON_FOREIGN_BRIDGE_ADDRESS = nativeToErcBridge.foreign
|
2019-05-06 14:12:53 +03:00
|
|
|
|
2020-02-11 20:50:34 +03:00
|
|
|
const validatorAddresses = [validator.address, secondValidator.address, thirdValidator.address]
|
|
|
|
|
2019-05-06 14:12:53 +03:00
|
|
|
homeWeb3.eth.accounts.wallet.add(user.privateKey)
|
|
|
|
homeWeb3.eth.accounts.wallet.add(validator.privateKey)
|
2019-06-04 14:27:21 +03:00
|
|
|
homeWeb3.eth.accounts.wallet.add(secondUser.privateKey)
|
2020-01-20 23:00:04 +03:00
|
|
|
homeWeb3.eth.accounts.wallet.add(secondValidator.privateKey)
|
|
|
|
homeWeb3.eth.accounts.wallet.add(thirdValidator.privateKey)
|
|
|
|
homeWeb3.eth.accounts.wallet.add(thirdUser.privateKey)
|
|
|
|
homeWeb3.eth.accounts.wallet.add(fourthUser.privateKey)
|
2019-05-06 14:12:53 +03:00
|
|
|
foreignWeb3.eth.accounts.wallet.add(user.privateKey)
|
|
|
|
foreignWeb3.eth.accounts.wallet.add(validator.privateKey)
|
2019-06-04 14:27:21 +03:00
|
|
|
foreignWeb3.eth.accounts.wallet.add(secondUser.privateKey)
|
2020-01-20 23:00:04 +03:00
|
|
|
foreignWeb3.eth.accounts.wallet.add(secondValidator.privateKey)
|
|
|
|
foreignWeb3.eth.accounts.wallet.add(thirdValidator.privateKey)
|
|
|
|
foreignWeb3.eth.accounts.wallet.add(thirdUser.privateKey)
|
|
|
|
foreignWeb3.eth.accounts.wallet.add(fourthUser.privateKey)
|
2019-05-06 14:12:53 +03:00
|
|
|
|
2019-07-12 11:53:16 +03:00
|
|
|
const token = new foreignWeb3.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, nativeToErcBridge.foreignToken)
|
2020-01-20 23:00:04 +03:00
|
|
|
const homeBridge = new homeWeb3.eth.Contract(HOME_NATIVE_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
|
|
|
const foreignBridge = new foreignWeb3.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
2019-05-06 14:12:53 +03:00
|
|
|
|
|
|
|
describe('native to erc', () => {
|
2020-01-20 23:00:04 +03:00
|
|
|
before(async () => {
|
|
|
|
// Set 2 required signatures for home bridge
|
|
|
|
await setRequiredSignatures({
|
|
|
|
bridgeContract: homeBridge,
|
|
|
|
web3: homeWeb3,
|
|
|
|
requiredSignatures: 2,
|
|
|
|
options: {
|
|
|
|
from: validator.address,
|
|
|
|
gas: '4000000'
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// Set 2 required signatures for foreign bridge
|
|
|
|
await setRequiredSignatures({
|
|
|
|
bridgeContract: foreignBridge,
|
|
|
|
web3: foreignWeb3,
|
|
|
|
requiredSignatures: 2,
|
|
|
|
options: {
|
|
|
|
from: validator.address,
|
|
|
|
gas: '4000000'
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
2019-05-06 14:12:53 +03:00
|
|
|
it('should convert eth in home to tokens in foreign', async () => {
|
|
|
|
// check that account has zero tokens in the foreign chain
|
|
|
|
const balance = await token.methods.balanceOf(user.address).call()
|
|
|
|
assert(toBN(balance).isZero(), 'Account should not have tokens yet')
|
|
|
|
|
|
|
|
// send transaction to home chain
|
2020-02-11 20:50:34 +03:00
|
|
|
await homeWeb3.eth.sendTransaction({
|
2019-05-06 14:12:53 +03:00
|
|
|
from: user.address,
|
2019-09-13 10:11:38 +03:00
|
|
|
to: COMMON_HOME_BRIDGE_ADDRESS,
|
2019-05-06 14:12:53 +03:00
|
|
|
gasPrice: '1',
|
|
|
|
gas: '50000',
|
|
|
|
value: '1000000000000000000'
|
|
|
|
})
|
|
|
|
|
|
|
|
// check that account has tokens in the foreign chain
|
2020-02-11 20:50:34 +03:00
|
|
|
await uniformRetry(async retry => {
|
2019-05-06 14:12:53 +03:00
|
|
|
const balance = await token.methods.balanceOf(user.address).call()
|
|
|
|
if (toBN(balance).isZero()) {
|
|
|
|
retry()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should convert tokens in foreign to eth in home', async () => {
|
|
|
|
const originalBalance = await homeWeb3.eth.getBalance(user.address)
|
|
|
|
|
|
|
|
// send tokens to foreign bridge
|
|
|
|
await token.methods
|
2019-09-13 10:11:38 +03:00
|
|
|
.transferAndCall(COMMON_FOREIGN_BRIDGE_ADDRESS, homeWeb3.utils.toWei('0.01'), '0x')
|
2019-05-06 14:12:53 +03:00
|
|
|
.send({
|
|
|
|
from: user.address,
|
|
|
|
gas: '1000000'
|
|
|
|
})
|
|
|
|
.catch(e => {
|
|
|
|
console.error(e)
|
|
|
|
})
|
|
|
|
|
|
|
|
// check that balance increases
|
2020-02-11 20:50:34 +03:00
|
|
|
await uniformRetry(async retry => {
|
2019-05-06 14:12:53 +03:00
|
|
|
const balance = await homeWeb3.eth.getBalance(user.address)
|
|
|
|
if (toBN(balance).lte(toBN(originalBalance))) {
|
|
|
|
retry()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should wait for funds if these are insufficient (Home)', async () => {
|
|
|
|
// check that account has zero tokens in the foreign chain
|
|
|
|
const originalBalance = toBN(await token.methods.balanceOf(user.address).call())
|
|
|
|
|
|
|
|
// empty validator funds
|
2019-06-04 14:27:21 +03:00
|
|
|
await sendAllBalance(homeWeb3, validator.address, secondUser.address)
|
2020-01-20 23:00:04 +03:00
|
|
|
await sendAllBalance(homeWeb3, secondValidator.address, thirdUser.address)
|
|
|
|
await sendAllBalance(homeWeb3, thirdValidator.address, fourthUser.address)
|
2019-05-06 14:12:53 +03:00
|
|
|
|
2020-02-11 20:50:34 +03:00
|
|
|
const nonces = await Promise.all(validatorAddresses.map(homeWeb3.eth.getTransactionCount))
|
2019-05-06 14:12:53 +03:00
|
|
|
// send transaction to home chain
|
2020-02-11 20:50:34 +03:00
|
|
|
await homeWeb3.eth.sendTransaction({
|
2019-05-06 14:12:53 +03:00
|
|
|
from: user.address,
|
2019-09-13 10:11:38 +03:00
|
|
|
to: COMMON_HOME_BRIDGE_ADDRESS,
|
2019-05-06 14:12:53 +03:00
|
|
|
gasPrice: '1',
|
|
|
|
gas: '50000',
|
|
|
|
value: '1000000000000000000'
|
|
|
|
})
|
|
|
|
|
|
|
|
// wait two seconds, no new blocks should have been generated
|
|
|
|
await sleep(2000)
|
2020-02-11 20:50:34 +03:00
|
|
|
const newNonces = await Promise.all(validatorAddresses.map(homeWeb3.eth.getTransactionCount))
|
2019-05-06 14:12:53 +03:00
|
|
|
const balance = toBN(await token.methods.balanceOf(user.address).call())
|
2020-02-11 20:50:34 +03:00
|
|
|
assert.deepStrictEqual(nonces, newNonces, "Shouldn't sent new tx")
|
2019-05-06 14:12:53 +03:00
|
|
|
assert(originalBalance.eq(balance), "Token balance shouldn't have changed")
|
|
|
|
|
|
|
|
// send funds back to validator
|
2020-01-20 23:00:04 +03:00
|
|
|
await sendAllBalance(homeWeb3, secondUser.address, validator.address)
|
|
|
|
await sendAllBalance(homeWeb3, thirdUser.address, secondValidator.address)
|
2020-02-11 20:50:34 +03:00
|
|
|
await sendAllBalance(homeWeb3, fourthUser.address, thirdValidator.address)
|
2019-05-06 14:12:53 +03:00
|
|
|
|
|
|
|
// check that token balance was incremented in foreign chain
|
2020-02-11 20:50:34 +03:00
|
|
|
await uniformRetry(async retry => {
|
2019-05-06 14:12:53 +03:00
|
|
|
const balance = toBN(await token.methods.balanceOf(user.address).call())
|
|
|
|
if (!balance.gt(originalBalance)) {
|
|
|
|
retry()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should wait for funds if these are insufficient (Foreign)', async () => {
|
|
|
|
// get original tokens balance
|
|
|
|
const originalBalance = toBN(await token.methods.balanceOf(user.address).call())
|
|
|
|
|
|
|
|
// empty foreign validator funds
|
2019-06-04 14:27:21 +03:00
|
|
|
await sendAllBalance(foreignWeb3, validator.address, secondUser.address)
|
2020-01-20 23:00:04 +03:00
|
|
|
await sendAllBalance(foreignWeb3, secondValidator.address, thirdUser.address)
|
|
|
|
await sendAllBalance(foreignWeb3, thirdValidator.address, fourthUser.address)
|
2020-02-11 20:50:34 +03:00
|
|
|
const nonces = await Promise.all(validatorAddresses.map(foreignWeb3.eth.getTransactionCount))
|
2019-05-06 14:12:53 +03:00
|
|
|
|
|
|
|
// send transaction to home chain
|
|
|
|
await homeWeb3.eth.sendTransaction({
|
|
|
|
from: user.address,
|
2019-09-13 10:11:38 +03:00
|
|
|
to: COMMON_HOME_BRIDGE_ADDRESS,
|
2019-05-06 14:12:53 +03:00
|
|
|
gasPrice: '1',
|
|
|
|
gas: '50000',
|
|
|
|
value: '1000000000000000000'
|
|
|
|
})
|
|
|
|
|
|
|
|
// tokens shouldn't be generated in the foreign chain because the validator doesn't have funds
|
|
|
|
await sleep(2000)
|
2020-02-11 20:50:34 +03:00
|
|
|
const newNonces = await Promise.all(validatorAddresses.map(foreignWeb3.eth.getTransactionCount))
|
|
|
|
assert.deepStrictEqual(nonces, newNonces, "Shouldn't sent new tx")
|
2019-05-06 14:12:53 +03:00
|
|
|
|
|
|
|
// send funds back to validator
|
2019-06-04 14:27:21 +03:00
|
|
|
await sendAllBalance(foreignWeb3, secondUser.address, validator.address)
|
2020-01-20 23:00:04 +03:00
|
|
|
await sendAllBalance(foreignWeb3, thirdUser.address, secondValidator.address)
|
|
|
|
await sendAllBalance(foreignWeb3, fourthUser.address, thirdValidator.address)
|
2019-05-06 14:12:53 +03:00
|
|
|
|
|
|
|
// check that account has tokens in the foreign chain
|
2020-02-11 20:50:34 +03:00
|
|
|
await uniformRetry(async retry => {
|
2019-05-06 14:12:53 +03:00
|
|
|
const balance = toBN(await token.methods.balanceOf(user.address).call())
|
|
|
|
if (balance.eq(originalBalance)) {
|
|
|
|
retry()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
async function sendAllBalance(web3, from, to) {
|
|
|
|
const balance = await web3.eth.getBalance(from)
|
|
|
|
const value = toBN(balance).sub(toBN('21000'))
|
|
|
|
|
|
|
|
return web3.eth.sendTransaction({
|
|
|
|
from,
|
|
|
|
to,
|
|
|
|
value,
|
|
|
|
gas: '21000',
|
|
|
|
gasPrice: '1'
|
|
|
|
})
|
|
|
|
}
|