From fd5086bb334bb279c608935431a6a32a2c803a04 Mon Sep 17 00:00:00 2001 From: Alexander Kolotov Date: Thu, 18 Apr 2019 16:47:50 +0300 Subject: [PATCH 1/3] Fee distribution events moved to the RewardableBridge contract --- contracts/upgradeable_contracts/BasicForeignBridge.sol | 4 ++-- contracts/upgradeable_contracts/RewardableBridge.sol | 9 +++++++-- .../erc20_to_erc20/ForeignBridgeErcToErc.sol | 2 +- .../erc20_to_native/ForeignBridgeErcToNative.sol | 2 +- .../erc20_to_native/HomeBridgeErcToNative.sol | 8 ++------ .../native_to_erc20/ForeignBridgeNativeToErc.sol | 4 ++-- .../native_to_erc20/HomeBridgeNativeToErc.sol | 5 +---- 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/contracts/upgradeable_contracts/BasicForeignBridge.sol b/contracts/upgradeable_contracts/BasicForeignBridge.sol index 5198a1a5f..365c4c169 100644 --- a/contracts/upgradeable_contracts/BasicForeignBridge.sol +++ b/contracts/upgradeable_contracts/BasicForeignBridge.sol @@ -21,14 +21,14 @@ contract BasicForeignBridge is EternalStorage, Validatable { require(contractAddress == address(this)); require(!relayedMessages(txHash)); setRelayedMessages(txHash, true); - require(onExecuteMessage(recipient, amount)); + require(onExecuteMessage(recipient, amount, txHash)); emit RelayedMessage(recipient, amount, txHash); } else { onFailedMessage(recipient, amount, txHash); } } - function onExecuteMessage(address, uint256) internal returns(bool); + function onExecuteMessage(address, uint256, bytes32) internal returns(bool); function setRelayedMessages(bytes32 _txHash, bool _status) internal { boolStorage[keccak256(abi.encodePacked("relayedMessages", _txHash))] = _status; diff --git a/contracts/upgradeable_contracts/RewardableBridge.sol b/contracts/upgradeable_contracts/RewardableBridge.sol index d21aeff26..295ca025c 100644 --- a/contracts/upgradeable_contracts/RewardableBridge.sol +++ b/contracts/upgradeable_contracts/RewardableBridge.sol @@ -6,6 +6,9 @@ import "./FeeTypes.sol"; contract RewardableBridge is Ownable, FeeTypes { + event FeeDistributedFromAffirmation(uint256 feeAmount, bytes32 indexed transactionHash); + event FeeDistributedFromSignatures(uint256 feeAmount, bytes32 indexed transactionHash); + function _getFee(bytes32 _feeType) internal view returns(uint256) { uint256 fee; address feeManager = feeManagerContract(); @@ -70,11 +73,13 @@ contract RewardableBridge is Ownable, FeeTypes { return fee; } - function distributeFeeFromSignatures(uint256 _fee, address _feeManager) internal { + function distributeFeeFromSignatures(uint256 _fee, address _feeManager, bytes32 _txHash) internal { require(_feeManager.delegatecall(abi.encodeWithSignature("distributeFeeFromSignatures(uint256)", _fee))); + emit FeeDistributedFromSignatures(_fee, _txHash); } - function distributeFeeFromAffirmation(uint256 _fee, address _feeManager) internal { + function distributeFeeFromAffirmation(uint256 _fee, address _feeManager, bytes32 _txHash) internal { require(_feeManager.delegatecall(abi.encodeWithSignature("distributeFeeFromAffirmation(uint256)", _fee))); + emit FeeDistributedFromAffirmation(_fee, _txHash); } } diff --git a/contracts/upgradeable_contracts/erc20_to_erc20/ForeignBridgeErcToErc.sol b/contracts/upgradeable_contracts/erc20_to_erc20/ForeignBridgeErcToErc.sol index 73a2a34ab..f609c8659 100644 --- a/contracts/upgradeable_contracts/erc20_to_erc20/ForeignBridgeErcToErc.sol +++ b/contracts/upgradeable_contracts/erc20_to_erc20/ForeignBridgeErcToErc.sol @@ -54,7 +54,7 @@ contract ForeignBridgeErcToErc is BasicBridge, BasicForeignBridge { return ERC20Basic(addressStorage[keccak256(abi.encodePacked("erc20token"))]); } - function onExecuteMessage(address _recipient, uint256 _amount) internal returns(bool){ + function onExecuteMessage(address _recipient, uint256 _amount, bytes32 _txHash) internal returns(bool){ setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount)); return erc20token().transfer(_recipient, _amount); } diff --git a/contracts/upgradeable_contracts/erc20_to_native/ForeignBridgeErcToNative.sol b/contracts/upgradeable_contracts/erc20_to_native/ForeignBridgeErcToNative.sol index c64317685..aa9e292b8 100644 --- a/contracts/upgradeable_contracts/erc20_to_native/ForeignBridgeErcToNative.sol +++ b/contracts/upgradeable_contracts/erc20_to_native/ForeignBridgeErcToNative.sol @@ -53,7 +53,7 @@ contract ForeignBridgeErcToNative is BasicBridge, BasicForeignBridge { return ERC20Basic(addressStorage[keccak256(abi.encodePacked("erc20token"))]); } - function onExecuteMessage(address _recipient, uint256 _amount) internal returns(bool) { + function onExecuteMessage(address _recipient, uint256 _amount, bytes32 _txHash) internal returns(bool) { setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount)); return erc20token().transfer(_recipient, _amount); } diff --git a/contracts/upgradeable_contracts/erc20_to_native/HomeBridgeErcToNative.sol b/contracts/upgradeable_contracts/erc20_to_native/HomeBridgeErcToNative.sol index 7f6f8da87..223380aaa 100644 --- a/contracts/upgradeable_contracts/erc20_to_native/HomeBridgeErcToNative.sol +++ b/contracts/upgradeable_contracts/erc20_to_native/HomeBridgeErcToNative.sol @@ -14,8 +14,6 @@ import "./RewardableHomeBridgeErcToNative.sol"; contract HomeBridgeErcToNative is EternalStorage, BasicBridge, BasicHomeBridge, OverdrawManagement, RewardableHomeBridgeErcToNative { event AmountLimitExceeded(address recipient, uint256 value, bytes32 transactionHash); - event FeeDistributedFromAffirmation(uint256 feeAmount, bytes32 indexed transactionHash); - event FeeDistributedFromSignatures(uint256 feeAmount, bytes32 indexed transactionHash); function () public payable { require(msg.value > 0); @@ -162,9 +160,8 @@ contract HomeBridgeErcToNative is EternalStorage, BasicBridge, BasicHomeBridge, address feeManager = feeManagerContract(); if (feeManager != address(0)) { uint256 fee = calculateFee(valueToMint, false, feeManager, FOREIGN_FEE); - distributeFeeFromAffirmation(fee, feeManager); + distributeFeeFromAffirmation(fee, feeManager, txHash); valueToMint = valueToMint.sub(fee); - emit FeeDistributedFromAffirmation(fee, txHash); } blockReward.addExtraReceiver(valueToMint, _recipient); return true; @@ -179,8 +176,7 @@ contract HomeBridgeErcToNative is EternalStorage, BasicBridge, BasicHomeBridge, address contractAddress; (recipient, amount, txHash, contractAddress) = Message.parseMessage(_message); uint256 fee = calculateFee(amount, true, feeManager, HOME_FEE); - distributeFeeFromSignatures(fee, feeManager); - emit FeeDistributedFromSignatures(fee, txHash); + distributeFeeFromSignatures(fee, feeManager, txHash); } } diff --git a/contracts/upgradeable_contracts/native_to_erc20/ForeignBridgeNativeToErc.sol b/contracts/upgradeable_contracts/native_to_erc20/ForeignBridgeNativeToErc.sol index 1821b279c..8c67e76ec 100644 --- a/contracts/upgradeable_contracts/native_to_erc20/ForeignBridgeNativeToErc.sol +++ b/contracts/upgradeable_contracts/native_to_erc20/ForeignBridgeNativeToErc.sol @@ -114,13 +114,13 @@ contract ForeignBridgeNativeToErc is ERC677Receiver, BasicBridge, BasicForeignBr setOwner(_owner); } - function onExecuteMessage(address _recipient, uint256 _amount) internal returns(bool) { + function onExecuteMessage(address _recipient, uint256 _amount, bytes32 _txHash) internal returns(bool) { setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount)); uint256 valueToMint = _amount; address feeManager = feeManagerContract(); if (feeManager != address(0)) { uint256 fee = calculateFee(valueToMint, false, feeManager, HOME_FEE); - distributeFeeFromSignatures(fee, feeManager); + distributeFeeFromSignatures(fee, feeManager, _txHash); valueToMint = valueToMint.sub(fee); } return erc677token().mint(_recipient, valueToMint); diff --git a/contracts/upgradeable_contracts/native_to_erc20/HomeBridgeNativeToErc.sol b/contracts/upgradeable_contracts/native_to_erc20/HomeBridgeNativeToErc.sol index e235f2c2b..9c97e4ba8 100644 --- a/contracts/upgradeable_contracts/native_to_erc20/HomeBridgeNativeToErc.sol +++ b/contracts/upgradeable_contracts/native_to_erc20/HomeBridgeNativeToErc.sol @@ -10,8 +10,6 @@ import "../Sacrifice.sol"; contract HomeBridgeNativeToErc is EternalStorage, BasicBridge, BasicHomeBridge, RewardableHomeBridgeNativeToErc { - event FeeDistributedFromAffirmation(uint256 feeAmount, bytes32 indexed transactionHash); - function () public payable { require(msg.value > 0); require(msg.data.length == 0); @@ -121,9 +119,8 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicBridge, BasicHomeBridge, address feeManager = feeManagerContract(); if (feeManager != address(0)) { uint256 fee = calculateFee(valueToTransfer, false, feeManager, FOREIGN_FEE); - distributeFeeFromAffirmation(fee, feeManager); + distributeFeeFromAffirmation(fee, feeManager, txHash); valueToTransfer = valueToTransfer.sub(fee); - emit FeeDistributedFromAffirmation(fee, txHash); } if (!_recipient.send(valueToTransfer)) { From 4326644a2d69c64ebb2bb661721bc2bca9e100ee Mon Sep 17 00:00:00 2001 From: Alexander Kolotov Date: Fri, 19 Apr 2019 09:14:04 +0300 Subject: [PATCH 2/3] tests cover emmiting fee dsitribution event for submitSignature call in the native-to-erc mode --- test/native_to_erc/foreign_bridge_test.js | 35 +++++++++++++++-------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/test/native_to_erc/foreign_bridge_test.js b/test/native_to_erc/foreign_bridge_test.js index 0a1fb406f..12640adf1 100644 --- a/test/native_to_erc/foreign_bridge_test.js +++ b/test/native_to_erc/foreign_bridge_test.js @@ -637,10 +637,14 @@ contract('ForeignBridge', async (accounts) => { const vrs = signatureToVRS(signature); const { logs } = await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled - logs[0].event.should.be.equal("RelayedMessage") - logs[0].args.recipient.should.be.equal(recipientAccount) - logs[0].args.value.should.be.bignumber.equal(value) - logs[0].args.transactionHash.should.be.equal(transactionHash); + + logs[0].event.should.be.equal("FeeDistributedFromSignatures") + logs[0].args.should.be.deep.equal({feeAmount, transactionHash}) + + logs[1].event.should.be.equal("RelayedMessage") + logs[1].args.recipient.should.be.equal(recipientAccount) + logs[1].args.value.should.be.bignumber.equal(value) + logs[1].args.transactionHash.should.be.equal(transactionHash); const balanceAfter = await token.balanceOf(recipientAccount); const totalSupplyAfter = await token.totalSupply(); @@ -657,6 +661,7 @@ contract('ForeignBridge', async (accounts) => { const feePerValidator = web3.toBigNumber(166666666666666) const feePerValidatorPlusDiff = web3.toBigNumber(166666666666668) const value = halfEther + const feeAmount = value.mul(web3.toBigNumber(fee)); const finalUserValue = value.mul(web3.toBigNumber(1-fee)); const validators = [accounts[1], accounts[2], accounts[3]] @@ -687,10 +692,13 @@ contract('ForeignBridge', async (accounts) => { const { logs } = await foreignBridge.executeSignatures([vrs.v, vrs2.v, vrs3.v], [vrs.r, vrs2.r, vrs3.r], [vrs.s, vrs2.s, vrs3.s], message).should.be.fulfilled // Then - logs[0].event.should.be.equal("RelayedMessage") - logs[0].args.recipient.should.be.equal(recipientAccount) - logs[0].args.value.should.be.bignumber.equal(value) - logs[0].args.transactionHash.should.be.equal(transactionHash); + logs[0].event.should.be.equal("FeeDistributedFromSignatures") + logs[0].args.should.be.deep.equal({feeAmount, transactionHash}) + + logs[1].event.should.be.equal("RelayedMessage") + logs[1].args.recipient.should.be.equal(recipientAccount) + logs[1].args.value.should.be.bignumber.equal(value) + logs[1].args.transactionHash.should.be.equal(transactionHash); const balanceAfter = await token.balanceOf(recipientAccount); const totalSupplyAfter = await token.totalSupply(); @@ -750,10 +758,13 @@ contract('ForeignBridge', async (accounts) => { const { logs } = await foreignBridge.executeSignatures([vrs.v, vrs2.v, vrs3.v], [vrs.r, vrs2.r, vrs3.r], [vrs.s, vrs2.s, vrs3.s], message).should.be.fulfilled // Then - logs[0].event.should.be.equal("RelayedMessage") - logs[0].args.recipient.should.be.equal(recipientAccount) - logs[0].args.value.should.be.bignumber.equal(value) - logs[0].args.transactionHash.should.be.equal(transactionHash); + logs[0].event.should.be.equal("FeeDistributedFromSignatures") + logs[0].args.should.be.deep.equal({feeAmount, transactionHash}) + + logs[1].event.should.be.equal("RelayedMessage") + logs[1].args.recipient.should.be.equal(recipientAccount) + logs[1].args.value.should.be.bignumber.equal(value) + logs[1].args.transactionHash.should.be.equal(transactionHash); const balanceAfter = await token.balanceOf(recipientAccount); const totalSupplyAfter = await token.totalSupply(); From b6df9b37fcc819b4773db44d010798b6ed69da0c Mon Sep 17 00:00:00 2001 From: Alexander Kolotov Date: Fri, 19 Apr 2019 09:15:03 +0300 Subject: [PATCH 3/3] syncronize node.js version in TravisCI with the requirements --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f26094479..77ff5d04b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ sudo: required group: beta language: node_js node_js: - - "9" + - "10" cache: yarn: true env: