Skip to content
Merged
3 changes: 2 additions & 1 deletion contracts/upgradeable_contracts/BaseBridgeValidators.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ contract BaseBridgeValidators is InitializableBridge, Ownable {
using SafeMath for uint256;

address public constant F_ADDR = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF;
uint256 internal constant MAX_VALIDATORS = 100;
uint256 internal constant MAX_VALIDATORS = 50;
bytes32 internal constant REQUIRED_SIGNATURES = 0xd18ea17c351d6834a0e568067fb71804d2a588d5e26d60f792b1c724b1bd53b1; // keccak256(abi.encodePacked("requiredSignatures"))
bytes32 internal constant VALIDATOR_COUNT = 0x8656d603d9f985c3483946a92789d52202f49736384ba131cb92f62c4c1aa082; // keccak256(abi.encodePacked("validatorCount"))

Expand Down Expand Up @@ -96,6 +96,7 @@ contract BaseBridgeValidators is InitializableBridge, Ownable {
}

function setValidatorCount(uint256 _validatorCount) internal {
require(_validatorCount <= MAX_VALIDATORS);
uintStorage[VALIDATOR_COUNT] = _validatorCount;
}

Expand Down
1 change: 0 additions & 1 deletion contracts/upgradeable_contracts/BridgeValidators.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ contract BridgeValidators is BaseBridgeValidators {
setOwner(_owner);
require(_requiredSignatures != 0);
require(_initialValidators.length >= _requiredSignatures);
require(_initialValidators.length <= MAX_VALIDATORS);

for (uint256 i = 0; i < _initialValidators.length; i++) {
require(_initialValidators[i] != address(0) && _initialValidators[i] != F_ADDR);
Expand Down
1 change: 0 additions & 1 deletion contracts/upgradeable_contracts/RewardableValidators.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ contract RewardableValidators is BaseBridgeValidators {
setOwner(_owner);
require(_requiredSignatures != 0);
require(_initialValidators.length >= _requiredSignatures);
require(_initialValidators.length <= MAX_VALIDATORS);
require(_initialValidators.length == _initialRewards.length);

for (uint256 i = 0; i < _initialValidators.length; i++) {
Expand Down
59 changes: 58 additions & 1 deletion test/erc_to_erc/home_bridge.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const OldBlockReward = artifacts.require('OldBlockReward')

const { expect } = require('chai')
const { ERROR_MSG, ZERO_ADDRESS, toBN } = require('../setup')
const { createMessage, sign, getEvents, ether, expectEventInLogs } = require('../helpers/helpers')
const { createMessage, sign, getEvents, ether, expectEventInLogs, createAccounts } = require('../helpers/helpers')

const minPerTx = ether('0.01')
const requireBlockConfirmations = 8
Expand All @@ -22,6 +22,8 @@ const halfEther = ether('0.5')
const foreignDailyLimit = oneEther
const foreignMaxPerTx = halfEther
const ZERO = toBN(0)
const MAX_GAS = 8000000
const MAX_VALIDATORS = 50
const decimalShiftZero = 0
const markedAsProcessed = toBN(2)
.pow(toBN(255))
Expand Down Expand Up @@ -1711,6 +1713,35 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
balanceRewardAddress4.should.be.bignumber.equal(feePerValidator)
balanceRewardAddress5.should.be.bignumber.equal(feePerValidator)
})
it('should distribute fee to max allowed number of validator', async () => {
// Given
const recipient = accounts[9]
const owner = accounts[0]
const validators = createAccounts(web3, MAX_VALIDATORS)
validators[0] = accounts[2]
const rewards = createAccounts(web3, MAX_VALIDATORS)
const requiredSignatures = 1
await rewardableValidators.initialize(requiredSignatures, validators, rewards, owner).should.be.fulfilled
await blockRewardContract.setValidatorsRewards(rewards)
await blockRewardContract.setToken(token.address)
await token.setBlockRewardContract(blockRewardContract.address, { from: owner })
await token.transferOwnership(homeBridge.address, { from: owner })

const valueCalc = 0.5 * (1 - fee)
const value = ether(valueCalc.toString())
const transactionHash = '0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80'
const message = createMessage(recipient, value, transactionHash, homeBridge.address)
const signature = await sign(validators[0], message)

const blockRewardBalanceBefore = await token.balanceOf(blockRewardContract.address)
blockRewardBalanceBefore.should.be.bignumber.equal('0')

// When
const { receipt } = await homeBridge.submitSignature(signature, message, {
from: validators[0]
}).should.be.fulfilled
expect(receipt.gasUsed).to.be.lte(MAX_GAS)
})
})
describe('#rewardable_executeAffirmation', () => {
let fee
Expand Down Expand Up @@ -1922,6 +1953,32 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
balanceRewardAddress4.should.be.bignumber.equal(feePerValidator)
balanceRewardAddress5.should.be.bignumber.equal(feePerValidator)
})

it('should distribute fee to max allowed number of validators', async () => {
// Given
const recipient = accounts[0]
const owner = accounts[0]
const validators = createAccounts(web3, MAX_VALIDATORS)
validators[0] = accounts[2]
const rewards = createAccounts(web3, MAX_VALIDATORS)
const requiredSignatures = 1
await rewardableValidators.initialize(requiredSignatures, validators, rewards, owner, {
from: owner
}).should.be.fulfilled
await blockRewardContract.setValidatorsRewards(rewards)
await blockRewardContract.setToken(token.address)
await token.setBlockRewardContract(blockRewardContract.address)
await token.transferOwnership(homeBridge.address)

const initialValue = halfEther
const transactionHash = '0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80'

// When
const { receipt } = await homeBridge.executeAffirmation(recipient, initialValue, transactionHash, {
from: validators[0]
}).should.be.fulfilled
expect(receipt.gasUsed).to.be.lte(MAX_GAS)
})
})
describe('#decimals Shift', async () => {
const decimalShiftTwo = 2
Expand Down
199 changes: 198 additions & 1 deletion test/erc_to_native/home_bridge.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const FeeManagerMock = artifacts.require('FeeManagerMock')

const { expect } = require('chai')
const { ERROR_MSG, ZERO_ADDRESS, toBN } = require('../setup')
const { createMessage, sign, ether, expectEventInLogs } = require('../helpers/helpers')
const { createMessage, sign, ether, expectEventInLogs, createAccounts } = require('../helpers/helpers')

const minPerTx = ether('0.01')
const requireBlockConfirmations = 8
Expand All @@ -21,6 +21,8 @@ const halfEther = ether('0.5')
const foreignDailyLimit = oneEther
const foreignMaxPerTx = halfEther
const ZERO = toBN(0)
const MAX_GAS = 8000000
const MAX_VALIDATORS = 50
const decimalShiftZero = 0

contract('HomeBridge_ERC20_to_Native', async accounts => {
Expand Down Expand Up @@ -2029,6 +2031,53 @@ contract('HomeBridge_ERC20_to_Native', async accounts => {
updatedBalanceRewardAddress4.should.be.bignumber.equal(initialBalanceRewardAddress4.add(feePerValidator))
updatedBalanceRewardAddress5.should.be.bignumber.equal(initialBalanceRewardAddress5.add(feePerValidator))
})

it('should distribute fee to max allowed number of validators', async () => {
// Initialize
const owner = accounts[0]
const validators = createAccounts(web3, MAX_VALIDATORS)
validators[0] = accounts[2]
const rewards = createAccounts(web3, MAX_VALIDATORS)
const requiredSignatures = 1
const rewardableValidators = await RewardableValidators.new()
const homeBridge = await HomeBridge.new()
await rewardableValidators.initialize(requiredSignatures, validators, rewards, owner, {
from: owner
}).should.be.fulfilled
await homeBridge.initialize(
rewardableValidators.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
blockRewardContract.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShiftZero
).should.be.fulfilled
await blockRewardContract.sendTransaction({
from: owner,
value: oneEther
}).should.be.fulfilled

// Given
const value = halfEther
// 0.1% fee
const fee = 0.001
const feeInWei = ether(fee.toString())
const feeManager = await FeeManagerErcToNative.new()
await homeBridge.setFeeManagerContract(feeManager.address, { from: owner }).should.be.fulfilled
await homeBridge.setForeignFee(feeInWei, { from: owner }).should.be.fulfilled

const recipient = '0xf4BEF13F9f4f2B203FAF0C3cBbaAbe1afE056955'

const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'

// When
const { receipt } = await homeBridge.executeAffirmation(recipient, value, transactionHash, {
from: validators[0]
})
expect(receipt.gasUsed).to.be.lte(MAX_GAS)
})
})
describe('#feeManager_fallback', async () => {
let homeBridge
Expand Down Expand Up @@ -2396,6 +2445,56 @@ contract('HomeBridge_ERC20_to_Native', async accounts => {
updatedBalanceRewardAddress4.should.be.bignumber.equal(initialBalanceRewardAddress4.add(feePerValidator))
updatedBalanceRewardAddress5.should.be.bignumber.equal(initialBalanceRewardAddress5.add(feePerValidator))
})
it('should distribute fee to max allowed number of validators', async () => {
// Initialize
const owner = accounts[0]
const validators = createAccounts(web3, MAX_VALIDATORS)
validators[0] = accounts[2]
const rewards = createAccounts(web3, MAX_VALIDATORS)
const requiredSignatures = 1
const rewardableValidators = await RewardableValidators.new()
const homeBridge = await HomeBridge.new()
await rewardableValidators.initialize(requiredSignatures, validators, rewards, owner, {
from: owner
}).should.be.fulfilled
await homeBridge.initialize(
rewardableValidators.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
blockRewardContract.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShiftZero
).should.be.fulfilled
await blockRewardContract.addMintedTotallyByBridge(oneEther, homeBridge.address)

// Given
// 0.1% fee
const fee = 0.001
const feeInWei = ether(fee.toString())
const feeManager = await FeeManagerErcToNative.new()
await homeBridge.setFeeManagerContract(feeManager.address, { from: owner }).should.be.fulfilled
await homeBridge.setHomeFee(feeInWei, { from: owner }).should.be.fulfilled

const recipient = accounts[0]
const initialValue = halfEther
const valueCalc = 0.5 * (1 - fee)
const value = ether(valueCalc.toString())
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'

// When
await homeBridge.sendTransaction({ from: recipient, value: initialValue }).should.be.fulfilled

const message = createMessage(recipient, value, transactionHash, homeBridge.address)

const signature = await sign(validators[0], message)

const { receipt } = await homeBridge.submitSignature(signature, message, {
from: validators[0]
}).should.be.fulfilled
expect(receipt.gasUsed).to.be.lte(MAX_GAS)
})
})
describe('#FeeManager_random', async () => {
it('should return value between 0 and 3', async () => {
Expand Down Expand Up @@ -2718,6 +2817,53 @@ contract('HomeBridge_ERC20_to_Native', async accounts => {
const feeAmountBlockReward = await blockRewardContract.feeAmount()
expect(toBN(feeAmountBlockReward)).to.be.bignumber.equal(feeAmount)
})
it('should distribute fee to max allowed number of validators', async () => {
// Initialize
const owner = accounts[0]
const validators = createAccounts(web3, MAX_VALIDATORS)
validators[0] = accounts[2]
const rewards = createAccounts(web3, MAX_VALIDATORS)
const requiredSignatures = 1
const rewardableValidators = await RewardableValidators.new()
const homeBridge = await HomeBridge.new()
await rewardableValidators.initialize(requiredSignatures, validators, rewards, owner, {
from: owner
}).should.be.fulfilled
await blockRewardContract.setValidatorsRewards(rewards)
await homeBridge.initialize(
rewardableValidators.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
blockRewardContract.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShiftZero
).should.be.fulfilled
await blockRewardContract.sendTransaction({
from: accounts[0],
value: oneEther
}).should.be.fulfilled

// Given
const value = halfEther
// 0.1% fee
const fee = 0.001
const feeInWei = ether(fee.toString())
const feeManager = await FeeManagerErcToNativePOSDAO.new()
await homeBridge.setFeeManagerContract(feeManager.address, { from: owner }).should.be.fulfilled
await homeBridge.setForeignFee(feeInWei, { from: owner }).should.be.fulfilled

const recipient = '0xf4BEF13F9f4f2B203FAF0C3cBbaAbe1afE056955'

const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'

// When
const { receipt } = await homeBridge.executeAffirmation(recipient, value, transactionHash, {
from: validators[0]
}).should.be.fulfilled
expect(receipt.gasUsed).to.be.lte(MAX_GAS)
})
})
describe('#feeManager_fallback_POSDAO', async () => {
let homeBridge
Expand Down Expand Up @@ -3116,6 +3262,57 @@ contract('HomeBridge_ERC20_to_Native', async accounts => {
const feeAmountBlockReward = await blockRewardContract.feeAmount()
feeAmountBlockReward.should.be.bignumber.equal(feeAmount)
})
it('should distribute fee to max allowed number of validators', async () => {
// Initialize
const owner = accounts[0]
const validators = createAccounts(web3, MAX_VALIDATORS)
validators[0] = accounts[2]
const rewards = createAccounts(web3, MAX_VALIDATORS)
const requiredSignatures = 1
const rewardableValidators = await RewardableValidators.new()
const homeBridge = await HomeBridge.new()
await rewardableValidators.initialize(requiredSignatures, validators, rewards, owner, {
from: owner
}).should.be.fulfilled
await blockRewardContract.setValidatorsRewards(rewards)
await homeBridge.initialize(
rewardableValidators.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
blockRewardContract.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShiftZero
).should.be.fulfilled
await blockRewardContract.addMintedTotallyByBridge(oneEther, homeBridge.address)

// Given
// 0.1% fee
const fee = 0.001
const feeInWei = ether(fee.toString())
const feeManager = await FeeManagerErcToNativePOSDAO.new()
await homeBridge.setFeeManagerContract(feeManager.address, { from: owner }).should.be.fulfilled
await homeBridge.setHomeFee(feeInWei, { from: owner }).should.be.fulfilled

const recipient = accounts[0]
const initialValue = halfEther
const valueCalc = 0.5 * (1 - fee)
const value = ether(valueCalc.toString())
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'

// When
await homeBridge.sendTransaction({ from: recipient, value: initialValue }).should.be.fulfilled

const message = createMessage(recipient, value, transactionHash, homeBridge.address)

const signature = await sign(validators[0], message)

const { receipt } = await homeBridge.submitSignature(signature, message, {
from: validators[0]
}).should.be.fulfilled
expect(receipt.gasUsed).to.be.lte(MAX_GAS)
})
})
describe('#decimals Shift', async () => {
const decimalShiftTwo = 2
Expand Down
Loading