Simplify mintReward function (#304)

This commit is contained in:
varasev 2019-10-12 06:32:14 +03:00 committed by Alexander Kolotov
parent 165d828437
commit 6de4ca4580
4 changed files with 77 additions and 66 deletions

View File

@ -33,21 +33,14 @@ contract ERC677BridgeTokenRewardable is ERC677BridgeToken {
_;
}
function mintReward(address[] _receivers, uint256[] _rewards) external onlyBlockRewardContract {
uint256 receiversLength = _receivers.length;
for (uint256 i = 0; i < receiversLength; i++) {
uint256 amount = _rewards[i];
if (amount == 0) continue;
address to = _receivers[i];
// Mint `amount` for `to`
totalSupply_ = totalSupply_.add(amount);
balances[to] = balances[to].add(amount);
emit Mint(to, amount);
emit Transfer(address(0), to, amount);
}
function mintReward(uint256 _amount) external onlyBlockRewardContract {
if (_amount == 0) return;
// Mint `_amount` for the BlockReward contract
address to = blockRewardContract;
totalSupply_ = totalSupply_.add(_amount);
balances[to] = balances[to].add(_amount);
emit Mint(to, _amount);
emit Transfer(address(0), to, _amount);
}
function stake(address _staker, uint256 _amount) external onlyStakingContract {
@ -58,11 +51,13 @@ contract ERC677BridgeTokenRewardable is ERC677BridgeToken {
}
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != blockRewardContract);
require(_to != stakingContract);
return super.transfer(_to, _value);
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != blockRewardContract);
require(_to != stakingContract);
return super.transferFrom(_from, _to, _value);
}

View File

@ -7,11 +7,12 @@ contract BlockReward {
using SafeMath for uint256;
address[] public validatorList;
uint256[] public validatorRewardList;
uint256 public mintedCoins = 0;
uint256 public feeAmount = 0;
mapping(bytes32 => uint256) internal uintStorage;
bytes32 internal constant MINTED_TOTALLY_BY_BRIDGE = "mintedTotallyByBridge";
bytes4 internal constant MINT_REWARD = 0xe2f764a3; // mintReward(address[],uint256[])
bytes4 internal constant MINT_REWARD = 0x91c0aabf; // mintReward(uint256)
address public token;
function() external payable {
@ -67,8 +68,7 @@ contract BlockReward {
}
function addBridgeTokenFeeReceivers(uint256 _amount) external {
address[] memory receivers = new address[](validatorList.length);
uint256[] memory rewards = new uint256[](validatorList.length);
validatorRewardList = new uint256[](validatorList.length);
feeAmount = _amount;
uint256 feePerValidator = _amount.div(validatorList.length);
@ -83,11 +83,10 @@ contract BlockReward {
if (diff > 0 && randomValidatorIndex == i) {
feeToDistribute = feeToDistribute.add(diff);
}
receivers[i] = validatorList[i];
rewards[i] = feeToDistribute;
validatorRewardList[i] = feeToDistribute;
}
require(token.call(abi.encodeWithSelector(MINT_REWARD, receivers, rewards)));
require(token.call(abi.encodeWithSelector(MINT_REWARD, _amount)));
}
function random(uint256 _count) public view returns (uint256) {

View File

@ -1541,8 +1541,8 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const message = createMessage(recipient, value, transactionHash, homeBridge.address)
const signature = await sign(validators[0], message)
const rewardAddressBalanceBefore = await token.balanceOf(rewards[0])
rewardAddressBalanceBefore.should.be.bignumber.equal('0')
const blockRewardBalanceBefore = await token.balanceOf(blockRewardContract.address)
blockRewardBalanceBefore.should.be.bignumber.equal('0')
// When
const { logs } = await homeBridge.submitSignature(signature, message, { from: validators[0] }).should.be.fulfilled
@ -1561,8 +1561,11 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const feeDistributed = await blockRewardContract.feeAmount()
feeDistributed.should.be.bignumber.equal(feeAmount)
const rewardAddressBalanceAfter = await token.balanceOf(rewards[0])
const rewardAddressBalanceAfter = await blockRewardContract.validatorRewardList(0)
rewardAddressBalanceAfter.should.be.bignumber.equal(feeAmount)
const blockRewardBalanceAfter = await token.balanceOf(blockRewardContract.address)
blockRewardBalanceAfter.should.be.bignumber.equal(feeAmount)
})
it('should distribute fee to 3 validators', async () => {
// Given
@ -1608,9 +1611,9 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const feeDistributed = await blockRewardContract.feeAmount()
feeDistributed.should.be.bignumber.equal(feeAmount)
const balanceRewardAddress1 = await token.balanceOf(rewards[0])
const balanceRewardAddress2 = await token.balanceOf(rewards[1])
const balanceRewardAddress3 = await token.balanceOf(rewards[2])
const balanceRewardAddress1 = await blockRewardContract.validatorRewardList(0)
const balanceRewardAddress2 = await blockRewardContract.validatorRewardList(1)
const balanceRewardAddress3 = await blockRewardContract.validatorRewardList(2)
expect(balanceRewardAddress1.eq(feePerValidator) || balanceRewardAddress1.eq(feePerValidatorPlusDiff)).to.equal(
true
@ -1667,11 +1670,11 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const feeDistributed = await blockRewardContract.feeAmount()
feeDistributed.should.be.bignumber.equal(feeAmount)
const balanceRewardAddress1 = await token.balanceOf(rewards[0])
const balanceRewardAddress2 = await token.balanceOf(rewards[1])
const balanceRewardAddress3 = await token.balanceOf(rewards[2])
const balanceRewardAddress4 = await token.balanceOf(rewards[3])
const balanceRewardAddress5 = await token.balanceOf(rewards[4])
const balanceRewardAddress1 = await blockRewardContract.validatorRewardList(0)
const balanceRewardAddress2 = await blockRewardContract.validatorRewardList(1)
const balanceRewardAddress3 = await blockRewardContract.validatorRewardList(2)
const balanceRewardAddress4 = await blockRewardContract.validatorRewardList(3)
const balanceRewardAddress5 = await blockRewardContract.validatorRewardList(4)
balanceRewardAddress1.should.be.bignumber.equal(feePerValidator)
balanceRewardAddress2.should.be.bignumber.equal(feePerValidator)
@ -1754,7 +1757,7 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const feeDistributed = await blockRewardContract.feeAmount()
feeDistributed.should.be.bignumber.equal(feeAmount)
const rewardAddressBalanceAfter = await token.balanceOf(rewards[0])
const rewardAddressBalanceAfter = await blockRewardContract.validatorRewardList(0)
rewardAddressBalanceAfter.should.be.bignumber.equal(feeAmount)
const recipientBalance = await token.balanceOf(recipient)
@ -1811,9 +1814,9 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const recipientBalance = await token.balanceOf(recipient)
recipientBalance.should.be.bignumber.equal(value)
const balanceRewardAddress1 = await token.balanceOf(rewards[0])
const balanceRewardAddress2 = await token.balanceOf(rewards[1])
const balanceRewardAddress3 = await token.balanceOf(rewards[2])
const balanceRewardAddress1 = await blockRewardContract.validatorRewardList(0)
const balanceRewardAddress2 = await blockRewardContract.validatorRewardList(1)
const balanceRewardAddress3 = await blockRewardContract.validatorRewardList(2)
expect(balanceRewardAddress1.eq(feePerValidator) || balanceRewardAddress1.eq(feePerValidatorPlusDiff)).to.equal(
true
@ -1878,11 +1881,11 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const recipientBalance = await token.balanceOf(recipient)
recipientBalance.should.be.bignumber.equal(value)
const balanceRewardAddress1 = await token.balanceOf(rewards[0])
const balanceRewardAddress2 = await token.balanceOf(rewards[1])
const balanceRewardAddress3 = await token.balanceOf(rewards[2])
const balanceRewardAddress4 = await token.balanceOf(rewards[3])
const balanceRewardAddress5 = await token.balanceOf(rewards[4])
const balanceRewardAddress1 = await blockRewardContract.validatorRewardList(0)
const balanceRewardAddress2 = await blockRewardContract.validatorRewardList(1)
const balanceRewardAddress3 = await blockRewardContract.validatorRewardList(2)
const balanceRewardAddress4 = await blockRewardContract.validatorRewardList(3)
const balanceRewardAddress5 = await blockRewardContract.validatorRewardList(4)
balanceRewardAddress1.should.be.bignumber.equal(feePerValidator)
balanceRewardAddress2.should.be.bignumber.equal(feePerValidator)

View File

@ -156,47 +156,39 @@ async function testERC677BridgeToken(accounts, rewardable) {
describe('#mintReward', async () => {
it('can only be called by BlockReward contract', async () => {
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled
await token.mintReward([], [], { from: user }).should.be.rejectedWith(ERROR_MSG)
await token.mintReward([], [], { from: accounts[2] }).should.be.fulfilled
await token.mintReward(1, { from: user }).should.be.rejectedWith(ERROR_MSG)
await token.mintReward(1, { from: accounts[2] }).should.be.fulfilled
})
it('should increase totalSupply and balances', async () => {
const user1 = accounts[1]
const user2 = accounts[2]
const user3 = accounts[3]
it('should increase totalSupply and balance', async () => {
expect(await token.totalSupply()).to.be.bignumber.equal(ZERO)
expect(await token.balanceOf(user1)).to.be.bignumber.equal(ZERO)
expect(await token.balanceOf(user2)).to.be.bignumber.equal(ZERO)
expect(await token.balanceOf(user3)).to.be.bignumber.equal(ZERO)
expect(await token.balanceOf(user)).to.be.bignumber.equal(ZERO)
await token.setBlockRewardContractMock(accounts[4]).should.be.fulfilled
await token.mintReward([user1, user2, user3], [100, 200, 300], { from: accounts[4] }).should.be.fulfilled
await token.setBlockRewardContractMock(user).should.be.fulfilled
await token.mintReward(100, { from: user }).should.be.fulfilled
expect(await token.totalSupply()).to.be.bignumber.equal('600')
expect(await token.balanceOf(user1)).to.be.bignumber.equal('100')
expect(await token.balanceOf(user2)).to.be.bignumber.equal('200')
expect(await token.balanceOf(user3)).to.be.bignumber.equal('300')
expect(await token.totalSupply()).to.be.bignumber.equal('100')
expect(await token.balanceOf(user)).to.be.bignumber.equal('100')
})
})
describe('#stake', async () => {
it('can only be called by Staking contract', async () => {
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled
await token.mintReward([user], ['100'], { from: accounts[2] }).should.be.fulfilled
await token.setStakingContractMock(accounts[3]).should.be.fulfilled
await token.stake(user, '100', { from: accounts[4] }).should.be.rejectedWith(ERROR_MSG)
await token.stake(user, '100', { from: accounts[3] }).should.be.fulfilled
await token.setBlockRewardContractMock(user).should.be.fulfilled
await token.mintReward('100', { from: user }).should.be.fulfilled
await token.setStakingContractMock(accounts[4]).should.be.fulfilled
await token.stake(user, '100', { from: accounts[3] }).should.be.rejectedWith(ERROR_MSG)
await token.stake(user, '100', { from: accounts[4] }).should.be.fulfilled
})
it("should revert if user doesn't have enough balance", async () => {
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled
await token.mintReward([user], ['99'], { from: accounts[2] }).should.be.fulfilled
await token.setBlockRewardContractMock(user).should.be.fulfilled
await token.mintReward('99', { from: user }).should.be.fulfilled
expect(await token.balanceOf(user)).to.be.bignumber.equal('99')
await token.setStakingContractMock(accounts[3]).should.be.fulfilled
await token.stake(user, '100', { from: accounts[3] }).should.be.rejectedWith(ERROR_MSG_OPCODE)
})
it("should decrease user's balance and increase Staking's balance", async () => {
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled
await token.mintReward([user], ['100'], { from: accounts[2] }).should.be.fulfilled
await token.setBlockRewardContractMock(user).should.be.fulfilled
await token.mintReward('100', { from: user }).should.be.fulfilled
expect(await token.balanceOf(user)).to.be.bignumber.equal('100')
expect(await token.balanceOf(accounts[3])).to.be.bignumber.equal(ZERO)
await token.setStakingContractMock(accounts[3]).should.be.fulfilled
@ -324,6 +316,15 @@ async function testERC677BridgeToken(accounts, rewardable) {
})
if (rewardable) {
it('fail to send tokens to BlockReward contract directly', async () => {
const amount = ether('1')
const blockRewardContractAddress = accounts[2]
const arbitraryAccountAddress = accounts[3]
await token.setBlockRewardContractMock(blockRewardContractAddress, { from: owner }).should.be.fulfilled
await token.mint(user, amount, { from: owner }).should.be.fulfilled
await token.transfer(blockRewardContractAddress, amount, { from: user }).should.be.rejectedWith(ERROR_MSG)
await token.transfer(arbitraryAccountAddress, amount, { from: user }).should.be.fulfilled
})
it('fail to send tokens to Staking contract directly', async () => {
const amount = ether('1')
const stakingContractAddress = accounts[2]
@ -356,6 +357,19 @@ async function testERC677BridgeToken(accounts, rewardable) {
expect(await receiver.data()).to.be.equal(null)
})
if (rewardable) {
it('fail to send tokens to BlockReward contract directly', async () => {
const amount = ether('1')
const user2 = accounts[2]
const blockRewardContractAddress = accounts[3]
const arbitraryAccountAddress = accounts[4]
await token.setBlockRewardContractMock(blockRewardContractAddress, { from: owner }).should.be.fulfilled
await token.mint(user, amount, { from: owner }).should.be.fulfilled
await token.approve(user2, amount, { from: user }).should.be.fulfilled
await token
.transferFrom(user, blockRewardContractAddress, amount, { from: user2 })
.should.be.rejectedWith(ERROR_MSG)
await token.transferFrom(user, arbitraryAccountAddress, amount, { from: user2 }).should.be.fulfilled
})
it('fail to send tokens to Staking contract directly', async () => {
const amount = ether('1')
const user2 = accounts[2]