Add random fee distribution on remaining fee difference

This commit is contained in:
Gerardo Nardelli 2019-01-14 12:16:32 -03:00
parent 4b8f53a014
commit 71870e0076
2 changed files with 65 additions and 9 deletions

View File

@ -40,14 +40,28 @@ contract BaseFeeManager is EternalStorage {
distributeFeeProportionally(_fee, REWARD_FOR_TRANSFERRING_FROM_HOME);
}
function random(uint256 _count) public view returns(uint256) {
return uint256(blockhash(block.number.sub(1))) % _count;
}
function distributeFeeProportionally(uint256 _fee, bytes32 _direction) internal {
IRewardableValidators validators = rewardableValidatorContract();
address [] memory validatorList = validators.validatorList();
address[] memory validatorList = validators.validatorList();
uint256 feePerValidator = _fee.div(validatorList.length);
uint256 randomValidatorIndex;
uint256 diff = _fee.sub(feePerValidator.mul(validatorList.length));
if (diff > 0) {
randomValidatorIndex = random(validatorList.length);
}
for (uint256 i = 0; i < validatorList.length; i++) {
uint256 feeToDistribute = feePerValidator;
if (diff > 0 && randomValidatorIndex == i) {
feeToDistribute = feeToDistribute.add(diff);
}
address rewardAddress = validators.getValidatorRewardAddress(validatorList[i]);
onFeeDistribution(rewardAddress, feePerValidator, _direction);
onFeeDistribution(rewardAddress, feeToDistribute, _direction);
}
}

View File

@ -899,6 +899,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
const requiredSignatures = 2
const rewardableValidators = await RewardableValidators.new()
const homeBridgeImpl = await HomeBridge.new();
const blockRewardContract = await BlockReward.new()
const storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
await storageProxy.upgradeTo('1', homeBridgeImpl.address).should.be.fulfilled
const homeBridge = await HomeBridge.at(storageProxy.address);
@ -906,16 +907,20 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
await homeBridge.initialize(rewardableValidators.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.fulfilled
await blockRewardContract.sendTransaction({
from: accounts[0],
value: oneEther
value: halfEther
}).should.be.fulfilled
// Given
const initialBlockRewardBalance = await web3.eth.getBalance(blockRewardContract.address)
initialBlockRewardBalance.should.be.bignumber.equal(halfEther)
const value = halfEther;
// 0.1% fee
const fee = 0.001
const feeInWei = web3.toBigNumber(web3.toWei(fee, "ether"))
// totalFee / 3
const feePerValidator = web3.toBigNumber(166666666666666)
const feePerValidatorPlusDiff = web3.toBigNumber(166666666666668)
const feeManager = await FeeManagerErcToNative.new()
await homeBridge.setFeeManagerContract(feeManager.address, { from: owner }).should.be.fulfilled
await homeBridge.setFee(feeInWei, { from: owner }).should.be.fulfilled
@ -955,9 +960,18 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
const updatedBalanceRewardAddress2 = await web3.eth.getBalance(rewards[1])
const updatedBalanceRewardAddress3 = await web3.eth.getBalance(rewards[2])
updatedBalanceRewardAddress1.should.be.bignumber.equal(initialBalanceRewardAddress1.add(feePerValidator))
updatedBalanceRewardAddress2.should.be.bignumber.equal(initialBalanceRewardAddress2.add(feePerValidator))
updatedBalanceRewardAddress3.should.be.bignumber.equal(initialBalanceRewardAddress3.add(feePerValidator))
expect(
updatedBalanceRewardAddress1.eq(initialBalanceRewardAddress1.add(feePerValidator))
|| updatedBalanceRewardAddress1.eq(initialBalanceRewardAddress1.add(feePerValidatorPlusDiff))).to.equal(true)
expect(
updatedBalanceRewardAddress2.eq(initialBalanceRewardAddress2.add(feePerValidator))
|| updatedBalanceRewardAddress2.eq(initialBalanceRewardAddress2.add(feePerValidatorPlusDiff))).to.equal(true)
expect(
updatedBalanceRewardAddress3.eq(initialBalanceRewardAddress3.add(feePerValidator))
|| updatedBalanceRewardAddress3.eq(initialBalanceRewardAddress3.add(feePerValidatorPlusDiff))).to.equal(true)
const blockRewardBalance = await web3.eth.getBalance(blockRewardContract.address)
blockRewardBalance.should.be.bignumber.equal('0')
})
it('should distribute fee to 5 validators', async () => {
// Initialize
@ -1156,6 +1170,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
const feeInWei = web3.toBigNumber(web3.toWei(fee, "ether"))
const feeManager = await FeeManagerErcToNative.new()
const feePerValidator = web3.toBigNumber(166666666666666)
const feePerValidatorPlusDiff = web3.toBigNumber(166666666666668)
await homeBridge.setFeeManagerContract(feeManager.address, { from: owner }).should.be.fulfilled
await homeBridge.setFee(feeInWei, { from: owner }).should.be.fulfilled
@ -1196,9 +1211,18 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
const updatedBalanceRewardAddress2 = await web3.eth.getBalance(rewards[1])
const updatedBalanceRewardAddress3 = await web3.eth.getBalance(rewards[2])
updatedBalanceRewardAddress1.should.be.bignumber.equal(initialBalanceRewardAddress1.add(feePerValidator))
updatedBalanceRewardAddress2.should.be.bignumber.equal(initialBalanceRewardAddress2.add(feePerValidator))
updatedBalanceRewardAddress3.should.be.bignumber.equal(initialBalanceRewardAddress3.add(feePerValidator))
const bridgeBalance = await web3.eth.getBalance(homeBridge.address)
bridgeBalance.should.be.bignumber.equal('0')
expect(
updatedBalanceRewardAddress1.eq(initialBalanceRewardAddress1.add(feePerValidator))
|| updatedBalanceRewardAddress1.eq(initialBalanceRewardAddress1.add(feePerValidatorPlusDiff))).to.equal(true)
expect(
updatedBalanceRewardAddress2.eq(initialBalanceRewardAddress2.add(feePerValidator))
|| updatedBalanceRewardAddress2.eq(initialBalanceRewardAddress2.add(feePerValidatorPlusDiff))).to.equal(true)
expect(
updatedBalanceRewardAddress3.eq(initialBalanceRewardAddress3.add(feePerValidator))
|| updatedBalanceRewardAddress3.eq(initialBalanceRewardAddress3.add(feePerValidatorPlusDiff))).to.equal(true)
})
it('should distribute fee to 5 validators', async () => {
// Initialize
@ -1276,4 +1300,22 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
updatedBalanceRewardAddress5.should.be.bignumber.equal(initialBalanceRewardAddress5.add(feePerValidator))
})
})
describe('#FeeManager_random', async () => {
it('should return value between 0 and 3', async () => {
// Given
const feeManager = await FeeManagerErcToNative.new()
for (let i = 0; i < 10; i++) {
// send Tx to generate new blocks
await feeManager.setFee(0).should.be.fulfilled
// When
const result = await feeManager.random(3);
// Then
result.should.be.bignumber.gte(0);
result.should.be.bignumber.lt(3);
}
})
})
})