Add execution limits to NATIVE-TO-ERC20 mode

This commit is contained in:
Gerardo Nardelli 2018-12-21 10:28:11 -03:00
parent 8bf7c1ae73
commit 06a9dcfe83
6 changed files with 161 additions and 50 deletions

View File

@ -28,9 +28,7 @@ contract BasicForeignBridge is EternalStorage, Validatable {
}
}
function onExecuteMessage(address, uint256) internal returns(bool){
// has to be defined
}
function onExecuteMessage(address, uint256) internal returns(bool);
function setRelayedMessages(bytes32 _txHash, bool _status) internal {
boolStorage[keccak256(abi.encodePacked("relayedMessages", _txHash))] = _status;
@ -40,10 +38,7 @@ contract BasicForeignBridge is EternalStorage, Validatable {
return boolStorage[keccak256(abi.encodePacked("relayedMessages", _txHash))];
}
function messageWithinLimits(uint256) internal view returns(bool) {
return true;
}
function messageWithinLimits(uint256) internal view returns(bool);
function onFailedMessage(address, uint256, bytes32) internal {
}
function onFailedMessage(address, uint256, bytes32) internal;
}

View File

@ -21,12 +21,15 @@ contract ForeignBridgeNativeToErc is ERC677Receiver, BasicBridge, BasicForeignBr
uint256 _minPerTx,
uint256 _foreignGasPrice,
uint256 _requiredBlockConfirmations,
uint256 _homeDailyLimit,
uint256 _homeMaxPerTx,
address _owner
) public returns(bool) {
require(!isInitialized());
require(_validatorContract != address(0) && isContract(_validatorContract));
require(_minPerTx > 0 && _maxPerTx > _minPerTx && _dailyLimit > _maxPerTx);
require(_foreignGasPrice > 0);
require(_homeMaxPerTx < _homeDailyLimit);
require(_owner != address(0));
addressStorage[keccak256(abi.encodePacked("validatorContract"))] = _validatorContract;
setErc677token(_erc677token);
@ -36,6 +39,8 @@ contract ForeignBridgeNativeToErc is ERC677Receiver, BasicBridge, BasicForeignBr
uintStorage[keccak256(abi.encodePacked("minPerTx"))] = _minPerTx;
uintStorage[keccak256(abi.encodePacked("gasPrice"))] = _foreignGasPrice;
uintStorage[keccak256(abi.encodePacked("requiredBlockConfirmations"))] = _requiredBlockConfirmations;
uintStorage[keccak256(abi.encodePacked("executionDailyLimit"))] = _homeDailyLimit;
uintStorage[keccak256(abi.encodePacked("executionMaxPerTx"))] = _homeMaxPerTx;
setOwner(_owner);
setInitialize(true);
return isInitialized();
@ -50,6 +55,7 @@ contract ForeignBridgeNativeToErc is ERC677Receiver, BasicBridge, BasicForeignBr
}
function onExecuteMessage(address _recipient, uint256 _amount) internal returns(bool){
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount));
return erc677token().mint(_recipient, _amount);
}
@ -57,4 +63,11 @@ contract ForeignBridgeNativeToErc is ERC677Receiver, BasicBridge, BasicForeignBr
emit UserRequestForAffirmation(_from, _value);
}
function messageWithinLimits(uint256 _amount) internal view returns(bool) {
return withinExecutionLimit(_amount);
}
function onFailedMessage(address, uint256, bytes32) internal {
revert();
}
}

View File

@ -20,6 +20,8 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicBridge, BasicHomeBridge {
uint256 _minPerTx,
uint256 _homeGasPrice,
uint256 _requiredBlockConfirmations,
uint256 _foreignDailyLimit,
uint256 _foreignMaxPerTx,
address _owner
) public
returns(bool)
@ -29,6 +31,7 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicBridge, BasicHomeBridge {
require(_homeGasPrice > 0);
require(_requiredBlockConfirmations > 0);
require(_minPerTx > 0 && _maxPerTx > _minPerTx && _dailyLimit > _maxPerTx);
require(_foreignMaxPerTx < _foreignDailyLimit);
require(_owner != address(0));
addressStorage[keccak256(abi.encodePacked("validatorContract"))] = _validatorContract;
uintStorage[keccak256(abi.encodePacked("deployedAtBlock"))] = block.number;
@ -37,6 +40,8 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicBridge, BasicHomeBridge {
uintStorage[keccak256(abi.encodePacked("minPerTx"))] = _minPerTx;
uintStorage[keccak256(abi.encodePacked("gasPrice"))] = _homeGasPrice;
uintStorage[keccak256(abi.encodePacked("requiredBlockConfirmations"))] = _requiredBlockConfirmations;
uintStorage[keccak256(abi.encodePacked("executionDailyLimit"))] = _foreignDailyLimit;
uintStorage[keccak256(abi.encodePacked("executionMaxPerTx"))] = _foreignMaxPerTx;
setOwner(_owner);
setInitialize(true);
return isInitialized();
@ -55,9 +60,18 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicBridge, BasicHomeBridge {
}
function onExecuteAffirmation(address _recipient, uint256 _value) internal returns(bool) {
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_value));
if (!_recipient.send(_value)) {
(new Sacrifice).value(_value)(_recipient);
}
return true;
}
function affirmationWithinLimits(uint256 _amount) internal view returns(bool) {
return withinExecutionLimit(_amount);
}
function onFailedAffirmation(address _recipient, uint256 _value, bytes32 _txHash) internal {
revert();
}
}

View File

@ -12,6 +12,8 @@ const minPerTx = web3.toBigNumber(web3.toWei(0.01, "ether"));
const Web3Utils = require('web3-utils');
const requireBlockConfirmations = 8;
const gasPrice = Web3Utils.toWei('1', 'gwei');
const homeDailyLimit = oneEther
const homeMaxPerTx = halfEther
const getEvents = function(contract, filter) {
return new Promise((resolve, reject) => {
@ -47,12 +49,12 @@ contract('ForeignBridge', async (accounts) => {
'0'.should.be.bignumber.equal(await foreignBridge.maxPerTx())
false.should.be.equal(await foreignBridge.isInitialized())
await foreignBridge.initialize(ZERO_ADDRESS, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner).should.be.rejectedWith(ERROR_MSG);
await foreignBridge.initialize(validatorContract.address, ZERO_ADDRESS, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner).should.be.rejectedWith(ERROR_MSG);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, 0, requireBlockConfirmations, owner).should.be.rejectedWith(ERROR_MSG);
await foreignBridge.initialize(owner, token.address, oneEther, halfEther, minPerTx, requireBlockConfirmations, gasPrice, owner).should.be.rejectedWith(ERROR_MSG);
await foreignBridge.initialize(validatorContract.address, owner, oneEther, halfEther, minPerTx, requireBlockConfirmations, gasPrice, owner).should.be.rejectedWith(ERROR_MSG);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignBridge.initialize(ZERO_ADDRESS, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
await foreignBridge.initialize(validatorContract.address, ZERO_ADDRESS, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, 0, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
await foreignBridge.initialize(owner, token.address, oneEther, halfEther, minPerTx, requireBlockConfirmations, gasPrice, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
await foreignBridge.initialize(validatorContract.address, owner, oneEther, halfEther, minPerTx, requireBlockConfirmations, gasPrice, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner);
true.should.be.equal(await foreignBridge.isInitialized())
validatorContract.address.should.be.equal(await foreignBridge.validatorContract());
@ -75,7 +77,7 @@ contract('ForeignBridge', async (accounts) => {
token = await POA20.new("POA ERC20 Foundation", "POA20", 18);
const oneEther = web3.toBigNumber(web3.toWei(1, "ether"));
const halfEther = web3.toBigNumber(web3.toWei(0.5, "ether"));
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner);
oneEther.should.be.bignumber.equal(await foreignBridge.dailyLimit());
await token.transferOwnership(foreignBridge.address);
})
@ -165,6 +167,43 @@ contract('ForeignBridge', async (accounts) => {
true.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message2).should.be.rejectedWith(ERROR_MSG)
})
it('should not allow withdraw over home max tx limit', async () => {
const recipientAccount = accounts[3];
const invalidValue = web3.toBigNumber(web3.toWei(0.75, "ether"));
const transactionHash = "0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121";
const message = createMessage(recipientAccount, invalidValue, transactionHash, foreignBridge.address);
const signature = await sign(authorities[0], message)
const vrs = signatureToVRS(signature);
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.rejectedWith(ERROR_MSG)
})
it('should not allow withdraw over daily home limit', async () => {
const recipientAccount = accounts[3];
const transactionHash = "0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121";
const message = createMessage(recipientAccount, halfEther, transactionHash, foreignBridge.address);
const signature = await sign(authorities[0], message)
const vrs = signatureToVRS(signature);
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
const transactionHash2 = "0x69debd8fd1923c9cb3cd8ef6461e2740b2d037943b941729d5a47671a2bb8712";
const message2 = createMessage(recipientAccount, halfEther, transactionHash2, foreignBridge.address);
const signature2 = await sign(authorities[0], message2)
const vrs2 = signatureToVRS(signature2);
await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.s], message2).should.be.fulfilled
const transactionHash3 = "0x022695428093bb292db8e48bd1417c5e1b84c0bf673bd0fff23ed0fb6495b872";
const message3 = createMessage(recipientAccount, halfEther, transactionHash3, foreignBridge.address);
const signature3 = await sign(authorities[0], message3)
const vrs3 = signatureToVRS(signature3);
await foreignBridge.executeSignatures([vrs3.v], [vrs3.r], [vrs3.s], message3).should.be.rejectedWith(ERROR_MSG)
})
})
describe('#executeSignatures with 2 minimum signatures', async () => {
@ -178,7 +217,7 @@ contract('ForeignBridge', async (accounts) => {
await multisigValidatorContract.initialize(2, twoAuthorities, ownerOfValidatorContract, {from: ownerOfValidatorContract})
foreignBridgeWithMultiSignatures = await ForeignBridge.new()
const oneEther = web3.toBigNumber(web3.toWei(1, "ether"));
await foreignBridgeWithMultiSignatures.initialize(multisigValidatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner, {from: ownerOfValidatorContract});
await foreignBridgeWithMultiSignatures.initialize(multisigValidatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner, {from: ownerOfValidatorContract});
await token.transferOwnership(foreignBridgeWithMultiSignatures.address);
})
it('deposit should fail if not enough signatures are provided', async () => {
@ -232,7 +271,7 @@ contract('ForeignBridge', async (accounts) => {
const value = web3.toBigNumber(web3.toWei(0.5, "ether"));
const foreignBridgeWithThreeSigs = await ForeignBridge.new()
await foreignBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, erc20Token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, erc20Token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner);
await erc20Token.transferOwnership(foreignBridgeWithThreeSigs.address);
const txHash = "0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121";
@ -266,7 +305,7 @@ contract('ForeignBridge', async (accounts) => {
const user = accounts[4]
token = await POA20.new("POA ERC20 Foundation", "POA20", 18, {from: owner});
foreignBridge = await ForeignBridge.new();
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner);
await token.mint(user, halfEther, {from: owner }).should.be.fulfilled;
await token.transferOwnership(foreignBridge.address, {from: owner});
await foreignBridge.onTokenTransfer(user, halfEther, '0x00', {from: owner}).should.be.rejectedWith(ERROR_MSG);
@ -280,7 +319,7 @@ contract('ForeignBridge', async (accounts) => {
const valueMoreThanLimit = halfEther.add(1);
token = await POA20.new("POA ERC20 Foundation", "POA20", 18, {from: owner});
foreignBridge = await ForeignBridge.new();
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner);
await token.mint(user, valueMoreThanLimit, {from: owner }).should.be.fulfilled;
await token.transferOwnership(foreignBridge.address, {from: owner});
await token.transferAndCall(foreignBridge.address, valueMoreThanLimit, '0x00', {from: user}).should.be.rejectedWith(ERROR_MSG);
@ -301,7 +340,7 @@ contract('ForeignBridge', async (accounts) => {
const valueMoreThanLimit = halfEther.add(1);
token = await POA20.new("POA ERC20 Foundation", "POA20", 18, {from: owner});
foreignBridge = await ForeignBridge.new();
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner);
await token.mint(user, oneEther.add(1), {from: owner }).should.be.fulfilled;
await token.transferOwnership(foreignBridge.address, {from: owner});
await token.transferAndCall(foreignBridge.address, valueMoreThanLimit, '0x00', {from: user}).should.be.rejectedWith(ERROR_MSG);
@ -322,7 +361,7 @@ contract('ForeignBridge', async (accounts) => {
const valueLessThanMinPerTx = minPerTx.sub(1);
token = await POA20.new("POA ERC20 Foundation", "POA20", 18, {from: owner});
foreignBridge = await ForeignBridge.new();
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner);
await token.mint(user, oneEther, {from: owner }).should.be.fulfilled;
await token.transferOwnership(foreignBridge.address, {from: owner});
await token.transferAndCall(foreignBridge.address, valueLessThanMinPerTx, '0x00', {from: user}).should.be.rejectedWith(ERROR_MSG);
@ -339,7 +378,7 @@ contract('ForeignBridge', async (accounts) => {
beforeEach(async () => {
token = await POA20.new("POA ERC20 Foundation", "POA20", 18);
foreignBridge = await ForeignBridge.new();
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner);
await token.transferOwnership(foreignBridge.address)
})
it('#setMaxPerTx allows to set only to owner and cannot be more than daily limit', async () => {
@ -383,7 +422,7 @@ contract('ForeignBridge', async (accounts) => {
await foreignBridgeProxy.upgradeTo('1', foreignBridgeImpl.address).should.be.fulfilled;
foreignBridgeProxy = await ForeignBridge.at(foreignBridgeProxy.address);
await foreignBridgeProxy.initialize(validatorsProxy.address, token.address, FOREIGN_DAILY_LIMIT, FOREIGN_MAX_AMOUNT_PER_TX, FOREIGN_MIN_AMOUNT_PER_TX, gasPrice, requireBlockConfirmations, owner)
await foreignBridgeProxy.initialize(validatorsProxy.address, token.address, FOREIGN_DAILY_LIMIT, FOREIGN_MAX_AMOUNT_PER_TX, FOREIGN_MIN_AMOUNT_PER_TX, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner)
await token.transferOwnership(foreignBridgeProxy.address).should.be.fulfilled;
foreignBridgeProxy.address.should.be.equal(await token.owner());
@ -404,7 +443,7 @@ contract('ForeignBridge', async (accounts) => {
let storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
let foreignBridge = await ForeignBridge.new();
let data = foreignBridge.initialize.request(
validatorsAddress, tokenAddress, FOREIGN_DAILY_LIMIT, FOREIGN_MAX_AMOUNT_PER_TX, FOREIGN_MIN_AMOUNT_PER_TX, gasPrice, requireBlockConfirmations, owner).params[0].data
validatorsAddress, tokenAddress, FOREIGN_DAILY_LIMIT, FOREIGN_MAX_AMOUNT_PER_TX, FOREIGN_MIN_AMOUNT_PER_TX, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner).params[0].data
await storageProxy.upgradeToAndCall('1', foreignBridge.address, data).should.be.fulfilled;
let finalContract = await ForeignBridge.at(storageProxy.address);
true.should.be.equal(await finalContract.isInitialized());
@ -418,7 +457,7 @@ contract('ForeignBridge', async (accounts) => {
const foreignBridge = await ForeignBridge.new();
const storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
const data = foreignBridge.initialize.request(
validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner).params[0].data
validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner).params[0].data
await storageProxy.upgradeToAndCall('1', foreignBridge.address, data).should.be.fulfilled;
await storageProxy.transferProxyOwnership(owner).should.be.fulfilled
})
@ -432,7 +471,7 @@ contract('ForeignBridge', async (accounts) => {
const storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
await storageProxy.upgradeTo('1', foreignBridgeImpl.address).should.be.fulfilled
const foreignBridge = await ForeignBridge.at(storageProxy.address);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner);
await token.transferOwnership(foreignBridge.address)
let tokenSecond = await POA20.new("Roman Token", "RST", 18);
@ -455,7 +494,7 @@ contract('ForeignBridge', async (accounts) => {
const storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
await storageProxy.upgradeTo('1', foreignBridgeImpl.address).should.be.fulfilled
const foreignBridge = await ForeignBridge.at(storageProxy.address);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, homeDailyLimit, homeMaxPerTx, owner);
await token.transferOwnership(foreignBridge.address)
let tokenSecond = await POA20.new("Roman Token", "RST", 18);

View File

@ -9,7 +9,10 @@ const minPerTx = web3.toBigNumber(web3.toWei(0.01, "ether"));
const requireBlockConfirmations = 8;
const gasPrice = Web3Utils.toWei('1', 'gwei');
const oneEther = web3.toBigNumber(web3.toWei(1, "ether"));
const twoEther = web3.toBigNumber(web3.toWei(2, "ether"));
const halfEther = web3.toBigNumber(web3.toWei(0.5, "ether"));
const foreignDailyLimit = oneEther
const foreignMaxPerTx = halfEther
contract('HomeBridge', async (accounts) => {
let homeContract, validatorContract, authorities, owner;
@ -29,7 +32,7 @@ contract('HomeBridge', async (accounts) => {
'0'.should.be.bignumber.equal(await homeContract.dailyLimit())
'0'.should.be.bignumber.equal(await homeContract.maxPerTx())
false.should.be.equal(await homeContract.isInitialized())
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, owner).should.be.fulfilled;
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner).should.be.fulfilled;
true.should.be.equal(await homeContract.isInitialized())
validatorContract.address.should.be.equal(await homeContract.validatorContract());
(await homeContract.deployedAtBlock()).should.be.bignumber.above(0);
@ -46,14 +49,14 @@ contract('HomeBridge', async (accounts) => {
})
it('cant set maxPerTx > dailyLimit', async () => {
false.should.be.equal(await homeContract.isInitialized())
await homeContract.initialize(validatorContract.address, '1', '2', '1', gasPrice, requireBlockConfirmations, owner).should.be.rejectedWith(ERROR_MSG);
await homeContract.initialize(validatorContract.address, '3', '2', '2', gasPrice, requireBlockConfirmations, owner).should.be.rejectedWith(ERROR_MSG);
await homeContract.initialize(validatorContract.address, '1', '2', '1', gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
await homeContract.initialize(validatorContract.address, '3', '2', '2', gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
false.should.be.equal(await homeContract.isInitialized())
})
it('can be deployed via upgradeToAndCall', async () => {
let storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
let data = homeContract.initialize.request(validatorContract.address, "3", "2", "1", gasPrice, requireBlockConfirmations, owner).params[0].data
let data = homeContract.initialize.request(validatorContract.address, "3", "2", "1", gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner).params[0].data
await storageProxy.upgradeToAndCall('1', homeContract.address, data).should.be.fulfilled;
let finalContract = await HomeBridge.at(storageProxy.address);
true.should.be.equal(await finalContract.isInitialized());
@ -64,15 +67,15 @@ contract('HomeBridge', async (accounts) => {
})
it('cant initialize with invalid arguments', async () => {
false.should.be.equal(await homeContract.isInitialized())
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, 0, owner).should.be.rejectedWith(ERROR_MSG);
await homeContract.initialize(owner, '3', '2', '1', gasPrice, requireBlockConfirmations, owner).should.be.rejectedWith(ERROR_MSG);
await homeContract.initialize(ZERO_ADDRESS, '3', '2', '1', gasPrice, requireBlockConfirmations, owner).should.be.rejectedWith(ERROR_MSG);
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, owner).should.be.fulfilled;
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, 0, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
await homeContract.initialize(owner, '3', '2', '1', gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
await homeContract.initialize(ZERO_ADDRESS, '3', '2', '1', gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner).should.be.fulfilled;
true.should.be.equal(await homeContract.isInitialized())
})
it('can transfer ownership', async () => {
let storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
let data = homeContract.initialize.request(validatorContract.address, "3", "2", "1", gasPrice, requireBlockConfirmations, owner).params[0].data
let data = homeContract.initialize.request(validatorContract.address, "3", "2", "1", gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner).params[0].data
await storageProxy.upgradeToAndCall('1', homeContract.address, data).should.be.fulfilled;
await storageProxy.transferProxyOwnership(owner).should.be.fulfilled
})
@ -81,7 +84,7 @@ contract('HomeBridge', async (accounts) => {
describe('#fallback', async () => {
beforeEach(async () => {
homeContract = await HomeBridge.new()
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, owner)
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner)
})
it('should accept POA', async () => {
const currentDay = await homeContract.getCurrentDay()
@ -156,7 +159,7 @@ contract('HomeBridge', async (accounts) => {
let homeContract;
beforeEach(async () => {
homeContract = await HomeBridge.new()
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, owner)
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner)
})
it('#setMaxPerTx allows to set only to owner and cannot be more than daily limit', async () => {
await homeContract.setMaxPerTx(2, {from: authorities[0]}).should.be.rejectedWith(ERROR_MSG);
@ -177,7 +180,7 @@ contract('HomeBridge', async (accounts) => {
let homeBridge;
beforeEach(async () => {
homeBridge = await HomeBridge.new();
await homeBridge.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await homeBridge.initialize(validatorContract.address, twoEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner);
const {logs} = await homeBridge.sendTransaction({
from: accounts[2],
value: halfEther
@ -216,7 +219,7 @@ contract('HomeBridge', async (accounts) => {
let ownerOfValidators = accounts[0]
await validatorContractWith2Signatures.initialize(2, authoritiesTwoAccs, ownerOfValidators)
let homeBridgeWithTwoSigs = await HomeBridge.new();
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, twoEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner);
await homeBridgeWithTwoSigs.sendTransaction({
from: accounts[2],
@ -286,7 +289,7 @@ contract('HomeBridge', async (accounts) => {
let ownerOfValidators = accounts[0]
await validatorContractWith2Signatures.initialize(2, authoritiesTwoAccs, ownerOfValidators)
let homeBridgeWithTwoSigs = await HomeBridge.new();
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner);
await homeBridgeWithTwoSigs.sendTransaction({
from: accounts[2],
@ -344,7 +347,7 @@ contract('HomeBridge', async (accounts) => {
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
const homeBridgeWithThreeSigs = await HomeBridge.new();
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner);
const value = web3.toBigNumber(web3.toWei(0.5, "ether"));
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
@ -371,6 +374,53 @@ contract('HomeBridge', async (accounts) => {
transactionHash
})
})
it('should not allow execute affirmation over foreign max tx limit', async () => {
const recipient = accounts[5];
const value = oneEther;
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.rejectedWith(ERROR_MSG);
})
it('should not allow execute affirmation over daily foreign limit', async () => {
await homeBridge.sendTransaction({ from: accounts[2], value: halfEther }).should.be.fulfilled;
await homeBridge.sendTransaction({ from: accounts[2], value: halfEther }).should.be.fulfilled;
const recipient = accounts[5];
const value = halfEther;
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
const { logs } = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled;
logs[0].event.should.be.equal("SignedForAffirmation");
logs[0].args.should.be.deep.equal({
signer: authorities[0],
transactionHash
});
logs[1].event.should.be.equal("AffirmationCompleted");
logs[1].args.should.be.deep.equal({
recipient,
value,
transactionHash
})
const transactionHash2 = "0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121";
const { logs: logs2 } = await homeBridge.executeAffirmation(recipient, value, transactionHash2, {from: authorities[0]}).should.be.fulfilled;
logs2[0].event.should.be.equal("SignedForAffirmation");
logs2[0].args.should.be.deep.equal({
signer: authorities[0],
transactionHash: transactionHash2
});
logs2[1].event.should.be.equal("AffirmationCompleted");
logs2[1].args.should.be.deep.equal({
recipient,
value,
transactionHash: transactionHash2
})
const transactionHash3 = "0x69debd8fd1923c9cb3cd8ef6461e2740b2d037943b941729d5a47671a2bb8712";
await homeBridge.executeAffirmation(recipient, value, transactionHash3, {from: authorities[0]}).should.be.rejectedWith(ERROR_MSG);
})
})
describe('#isAlreadyProcessed', async () => {
it('returns ', async () => {
@ -391,7 +441,7 @@ contract('HomeBridge', async (accounts) => {
ownerOfValidators = accounts[0]
await validatorContractWith2Signatures.initialize(2, authoritiesTwoAccs, ownerOfValidators)
homeBridgeWithTwoSigs = await HomeBridge.new();
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner);
})
it('allows a validator to submit a signature', async () => {
var recipientAccount = accounts[8]
@ -434,7 +484,7 @@ contract('HomeBridge', async (accounts) => {
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
const homeBridgeWithThreeSigs = await HomeBridge.new();
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner);
const value = web3.toBigNumber(web3.toWei(0.5, "ether"));
const transactionHash = "0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80";

View File

@ -10,8 +10,8 @@ const requireBlockConfirmations = 8;
const gasPrice = Web3Utils.toWei('1', 'gwei');
const oneEther = web3.toBigNumber(web3.toWei(1, "ether"));
const halfEther = web3.toBigNumber(web3.toWei(0.5, "ether"));
const foreignDailyLimit = oneEther
const foreignMaxPerTx = halfEther
const executionDailyLimit = oneEther
const executionMaxPerTx = halfEther
contract('ERC677BridgeToken', async (accounts) => {
let token
@ -103,9 +103,9 @@ contract('ERC677BridgeToken', async (accounts) => {
const authorities = [accounts[2]];
await validatorContract.initialize(1, authorities, owner)
homeErcToErcContract = await HomeErcToErcBridge.new()
await homeErcToErcContract.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner)
await homeErcToErcContract.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address, executionDailyLimit, executionMaxPerTx, owner)
foreignNativeToErcBridge = await ForeignNativeToErcBridge.new()
await foreignNativeToErcBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignNativeToErcBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, executionDailyLimit, executionMaxPerTx, owner);
})
it('sends tokens to recipient', async () => {
await token.mint(user, 1, {from: owner }).should.be.fulfilled;
@ -191,9 +191,9 @@ contract('ERC677BridgeToken', async (accounts) => {
const authorities = [accounts[2]];
await validatorContract.initialize(1, authorities, owner)
homeErcToErcContract = await HomeErcToErcBridge.new()
await homeErcToErcContract.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner)
await homeErcToErcContract.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address, executionDailyLimit, executionMaxPerTx, owner)
foreignNativeToErcBridge = await ForeignNativeToErcBridge.new()
await foreignNativeToErcBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, owner);
await foreignNativeToErcBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, executionDailyLimit, executionMaxPerTx, owner);
})
it('calls contractFallback', async () => {
const receiver = await ERC677ReceiverTest.new();