Add execution limits to NATIVE-TO-ERC20 mode
This commit is contained in:
parent
8bf7c1ae73
commit
06a9dcfe83
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue