Single execute signatures (#357)
This commit is contained in:
parent
8f11c7dae3
commit
34a8d2fdc7
|
@ -96,31 +96,19 @@ library Message {
|
|||
}
|
||||
}
|
||||
|
||||
function hasEnoughValidSignatures(
|
||||
bytes _message,
|
||||
uint8[] _vs,
|
||||
bytes32[] _rs,
|
||||
bytes32[] _ss,
|
||||
IBridgeValidators _validatorContract,
|
||||
bool isAMBMessage
|
||||
) internal view {
|
||||
require(isAMBMessage || isMessageValid(_message));
|
||||
uint256 requiredSignatures = _validatorContract.requiredSignatures();
|
||||
// It is not necessary to check that arrays have the same length since it will be handled
|
||||
// during attempt to access to the corresponding elements in the loop and the call will be reverted.
|
||||
// It will save gas for the rational validators actions and still be safe enough from security point of view
|
||||
require(_vs.length >= requiredSignatures);
|
||||
bytes32 hash = hashMessage(_message, isAMBMessage);
|
||||
address[] memory encounteredAddresses = new address[](requiredSignatures);
|
||||
|
||||
for (uint256 i = 0; i < requiredSignatures; i++) {
|
||||
address recoveredAddress = ecrecover(hash, _vs[i], _rs[i], _ss[i]);
|
||||
require(_validatorContract.isValidator(recoveredAddress));
|
||||
require(!addressArrayContains(encounteredAddresses, recoveredAddress));
|
||||
encounteredAddresses[i] = recoveredAddress;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Validates provided signatures, only first requiredSignatures() number
|
||||
* of signatures are going to be validated, these signatures should be from different validators.
|
||||
* @param _message bytes message used to generate signatures
|
||||
* @param _signatures bytes blob with signatures to be validated.
|
||||
* First byte X is a number of signatures in a blob,
|
||||
* next X bytes are v components of signatures,
|
||||
* next 32 * X bytes are r components of signatures,
|
||||
* next 32 * X bytes are s components of signatures.
|
||||
* @param _validatorContract contract, which conforms to the IBridgeValidators interface,
|
||||
* where info about current validators and required signatures is stored.
|
||||
* @param isAMBMessage true if _message is an AMB message with arbitrary length.
|
||||
*/
|
||||
function hasEnoughValidSignatures(
|
||||
bytes _message,
|
||||
bytes _signatures,
|
||||
|
|
|
@ -15,8 +15,14 @@ contract BasicForeignBridge is EternalStorage, Validatable, BasicBridge, BasicTo
|
|||
event RelayedMessage(address recipient, uint256 value, bytes32 transactionHash);
|
||||
event UserRequestForAffirmation(address recipient, uint256 value);
|
||||
|
||||
function executeSignatures(uint8[] vs, bytes32[] rs, bytes32[] ss, bytes message) external {
|
||||
Message.hasEnoughValidSignatures(message, vs, rs, ss, validatorContract(), false);
|
||||
/**
|
||||
* @dev Validates provided signatures and relays a given message
|
||||
* @param message bytes to be relayed
|
||||
* @param signatures bytes blob with signatures to be validated
|
||||
*/
|
||||
function executeSignatures(bytes message, bytes signatures) external {
|
||||
Message.hasEnoughValidSignatures(message, signatures, validatorContract(), false);
|
||||
|
||||
address recipient;
|
||||
uint256 amount;
|
||||
bytes32 txHash;
|
||||
|
|
|
@ -2,7 +2,7 @@ pragma solidity 0.4.24;
|
|||
|
||||
contract VersionableBridge {
|
||||
function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) {
|
||||
return (2, 5, 0);
|
||||
return (3, 0, 0);
|
||||
}
|
||||
|
||||
/* solcov ignore next */
|
||||
|
|
|
@ -8,6 +8,11 @@ import "./MessageProcessor.sol";
|
|||
import "../MessageRelay.sol";
|
||||
|
||||
contract BasicForeignAMB is BasicAMB, MessageRelay, MessageDelivery, MessageProcessor {
|
||||
/**
|
||||
* @dev Validates provided signatures and relays a given message
|
||||
* @param _data bytes to be relayed
|
||||
* @param _signatures bytes blob with signatures to be validated
|
||||
*/
|
||||
function executeSignatures(bytes _data, bytes _signatures) external {
|
||||
Message.hasEnoughValidSignatures(_data, _signatures, validatorContract(), true);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ const {
|
|||
ether,
|
||||
expectEventInLogs,
|
||||
addTxHashToAMBData,
|
||||
signatureToVRSAMB,
|
||||
signatureToVRS,
|
||||
packSignatures,
|
||||
createFullAccounts
|
||||
} = require('../helpers/helpers')
|
||||
|
@ -244,7 +244,7 @@ contract('ForeignAMB', async accounts => {
|
|||
const message = addTxHashToAMBData(encodedData, resultPassMessageTx.tx)
|
||||
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRSAMB(signature)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const signatures = packSignatures([vrs])
|
||||
|
||||
const { logs } = await foreignBridge.executeSignatures(message, signatures, {
|
||||
|
@ -300,13 +300,13 @@ contract('ForeignAMB', async accounts => {
|
|||
const message = addTxHashToAMBData(encodedData, resultPassMessageTx.tx)
|
||||
|
||||
const signature1 = await sign(authoritiesFiveAccs[0], message)
|
||||
const vrs = signatureToVRSAMB(signature1)
|
||||
const vrs = signatureToVRS(signature1)
|
||||
|
||||
const signature2 = await sign(authoritiesFiveAccs[1], message)
|
||||
const vrs2 = signatureToVRSAMB(signature2)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
|
||||
const signature3 = await sign(authoritiesFiveAccs[2], message)
|
||||
const vrs3 = signatureToVRSAMB(signature3)
|
||||
const vrs3 = signatureToVRS(signature3)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
const twoSignatures = packSignatures([vrs, vrs2])
|
||||
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
|
||||
|
@ -376,7 +376,7 @@ contract('ForeignAMB', async accounts => {
|
|||
const vrsList = []
|
||||
for (let i = 0; i < MAX_SIGNATURES; i++) {
|
||||
const { signature } = await authorities[i].sign(message)
|
||||
vrsList[i] = signatureToVRSAMB(signature)
|
||||
vrsList[i] = signatureToVRS(signature)
|
||||
}
|
||||
|
||||
const signatures = packSignatures(vrsList)
|
||||
|
@ -400,7 +400,7 @@ contract('ForeignAMB', async accounts => {
|
|||
const message = addTxHashToAMBData(encodedData, resultPassMessageTx.tx)
|
||||
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRSAMB(signature)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const signatures = packSignatures([vrs])
|
||||
|
||||
const { logs } = await foreignBridge.executeSignatures(message, signatures, {
|
||||
|
@ -434,7 +434,7 @@ contract('ForeignAMB', async accounts => {
|
|||
const message = addTxHashToAMBData(encodedData, resultPassMessageTx.tx)
|
||||
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRSAMB(signature)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const signatures = packSignatures([vrs])
|
||||
|
||||
const { logs } = await foreignBridge.executeSignatures(message, signatures, {
|
||||
|
@ -467,7 +467,7 @@ contract('ForeignAMB', async accounts => {
|
|||
const message = addTxHashToAMBData(encodedData, resultPassMessageTx.tx)
|
||||
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRSAMB(signature)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const signatures = packSignatures([vrs])
|
||||
|
||||
const { logs } = await foreignBridge.executeSignatures(message, signatures, {
|
||||
|
@ -509,7 +509,7 @@ contract('ForeignAMB', async accounts => {
|
|||
const message = addTxHashToAMBData(encodedData, resultPassMessageTx.tx)
|
||||
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRSAMB(signature)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const signatures = packSignatures([vrs])
|
||||
|
||||
const { logs } = await foreignBridge.executeSignatures(message, signatures, {
|
||||
|
|
|
@ -14,7 +14,8 @@ const {
|
|||
ether,
|
||||
getEvents,
|
||||
expectEventInLogs,
|
||||
createFullAccounts
|
||||
createFullAccounts,
|
||||
packSignatures
|
||||
} = require('../helpers/helpers')
|
||||
|
||||
const oneEther = ether('1')
|
||||
|
@ -217,8 +218,9 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
const { logs } = await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).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)
|
||||
|
@ -237,16 +239,18 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
// tx 2
|
||||
await token.mint(foreignBridge.address, value)
|
||||
const transactionHash2 = '0x77a496628a776a03d58d7e6059a5937f04bebd8ba4ff89f76dd4bb8ba7e291ee'
|
||||
const message2 = createMessage(recipientAccount, value, transactionHash2, foreignBridge.address)
|
||||
const signature2 = await sign(authorities[0], message2)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
const oneSignature2 = packSignatures([vrs2])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash2))
|
||||
const { logs } = await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.s], message2).should.be.fulfilled
|
||||
const { logs } = await foreignBridge.executeSignatures(message2, oneSignature2).should.be.fulfilled
|
||||
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipientAccount)
|
||||
|
@ -264,15 +268,17 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
// tx 2
|
||||
await token.mint(foreignBridge.address, value)
|
||||
const message2 = createMessage(accounts[4], value, transactionHash, foreignBridge.address)
|
||||
const signature2 = await sign(authorities[0], message2)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
const oneSignature2 = packSignatures([vrs2])
|
||||
true.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.s], message2).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridge.executeSignatures(message2, oneSignature2).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
|
||||
it('should not allow withdraw over home max tx limit', async () => {
|
||||
|
@ -284,8 +290,9 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
const message = createMessage(recipientAccount, invalidValue, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridge.executeSignatures(message, oneSignature).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
|
||||
it('should not allow withdraw over daily home limit', async () => {
|
||||
|
@ -296,22 +303,25 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
const message = createMessage(recipientAccount, halfEther, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message, oneSignature).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)
|
||||
const oneSignature2 = packSignatures([vrs2])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.s], message2).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message2, oneSignature2).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)
|
||||
const oneSignature3 = packSignatures([vrs3])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs3.v], [vrs3.r], [vrs3.s], message3).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridge.executeSignatures(message3, oneSignature3).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
})
|
||||
describe('#withdraw with 2 minimum signatures', async () => {
|
||||
|
@ -349,19 +359,15 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridgeWithMultiSignatures.address)
|
||||
const signature = await sign(twoAuthorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridgeWithMultiSignatures.relayedMessages(transactionHash))
|
||||
await foreignBridgeWithMultiSignatures
|
||||
.executeSignatures([vrs.v], [vrs.r], [vrs.s], message)
|
||||
.should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridgeWithMultiSignatures.executeSignatures(message, oneSignature).should.be.rejectedWith(ERROR_MSG)
|
||||
// msg 2
|
||||
const signature2 = await sign(twoAuthorities[1], message)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
const { logs } = await foreignBridgeWithMultiSignatures.executeSignatures(
|
||||
[vrs.v, vrs2.v],
|
||||
[vrs.r, vrs2.r],
|
||||
[vrs.s, vrs2.s],
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const twoSignatures = packSignatures([vrs, vrs2])
|
||||
const { logs } = await foreignBridgeWithMultiSignatures.executeSignatures(message, twoSignatures).should.be
|
||||
.fulfilled
|
||||
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipientAccount)
|
||||
|
@ -374,10 +380,9 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridgeWithMultiSignatures.address)
|
||||
const signature = await sign(twoAuthorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const twoSignatures = packSignatures([vrs, vrs])
|
||||
false.should.be.equal(await foreignBridgeWithMultiSignatures.relayedMessages(transactionHash))
|
||||
await foreignBridgeWithMultiSignatures
|
||||
.executeSignatures([vrs.v, vrs.v], [vrs.r, vrs.r], [vrs.s, vrs.s], message)
|
||||
.should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridgeWithMultiSignatures.executeSignatures(message, twoSignatures).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
|
||||
it('works with 5 validators and 3 required signatures', async () => {
|
||||
|
@ -417,12 +422,9 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
const signature3 = await sign(authoritiesFiveAccs[2], message)
|
||||
const vrs3 = signatureToVRS(signature3)
|
||||
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(
|
||||
[vrs.v, vrs2.v, vrs3.v],
|
||||
[vrs.r, vrs2.r, vrs3.r],
|
||||
[vrs.s, vrs2.s, vrs3.s],
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
|
||||
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(message, threeSignatures).should.be.fulfilled
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipient)
|
||||
logs[0].args.value.should.be.bignumber.equal(value)
|
||||
|
@ -462,12 +464,9 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
vrsList[i] = signatureToVRS(signature)
|
||||
}
|
||||
|
||||
const { receipt } = await foreignBridgeWithMaxSigs.executeSignatures(
|
||||
vrsList.map(vrs => vrs.v),
|
||||
vrsList.map(vrs => vrs.r),
|
||||
vrsList.map(vrs => vrs.s),
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const maxSignatures = packSignatures(vrsList)
|
||||
|
||||
const { receipt } = await foreignBridgeWithMaxSigs.executeSignatures(message, maxSignatures).should.be.fulfilled
|
||||
expect(receipt.gasUsed).to.be.lte(MAX_GAS)
|
||||
})
|
||||
})
|
||||
|
@ -798,8 +797,9 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
const message = createMessage(recipientAccount, valueOnHome, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
const { logs } = await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).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(valueOnHome)
|
||||
|
@ -853,12 +853,9 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
|
|||
const signature3 = await sign(authoritiesFiveAccs[2], message)
|
||||
const vrs3 = signatureToVRS(signature3)
|
||||
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(
|
||||
[vrs.v, vrs2.v, vrs3.v],
|
||||
[vrs.r, vrs2.r, vrs3.r],
|
||||
[vrs.s, vrs2.s, vrs3.s],
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
|
||||
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(message, threeSignatures).should.be.fulfilled
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipient)
|
||||
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
|
||||
|
|
|
@ -18,7 +18,8 @@ const {
|
|||
ether,
|
||||
expectEventInLogs,
|
||||
getEvents,
|
||||
createFullAccounts
|
||||
createFullAccounts,
|
||||
packSignatures
|
||||
} = require('../helpers/helpers')
|
||||
|
||||
const halfEther = ether('0.5')
|
||||
|
@ -240,9 +241,10 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
|
||||
const { logs } = await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipientAccount)
|
||||
|
@ -264,9 +266,10 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
|
||||
// tx 2
|
||||
await token.mint(foreignBridge.address, value)
|
||||
|
@ -274,9 +277,10 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const message2 = createMessage(recipientAccount, value, transactionHash2, foreignBridge.address)
|
||||
const signature2 = await sign(authorities[0], message2)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
const oneSignature2 = packSignatures([vrs2])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash2))
|
||||
|
||||
const { logs } = await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.s], message2).should.be.fulfilled
|
||||
const { logs } = await foreignBridge.executeSignatures(message2, oneSignature2).should.be.fulfilled
|
||||
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipientAccount)
|
||||
|
@ -295,18 +299,20 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
|
||||
// tx 2
|
||||
await token.mint(foreignBridge.address, value)
|
||||
const message2 = createMessage(accounts[4], value, transactionHash, foreignBridge.address)
|
||||
const signature2 = await sign(authorities[0], message2)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
const oneSignature2 = packSignatures([vrs2])
|
||||
true.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
|
||||
await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.s], message2).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridge.executeSignatures(message2, oneSignature2).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
|
||||
it('should not allow withdraw over home max tx limit', async () => {
|
||||
|
@ -318,8 +324,9 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const message = createMessage(recipientAccount, invalidValue, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridge.executeSignatures(message, oneSignature).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
|
||||
it('should not allow withdraw over daily home limit', async () => {
|
||||
|
@ -330,22 +337,25 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const message = createMessage(recipientAccount, halfEther, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message, oneSignature).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)
|
||||
const oneSignature2 = packSignatures([vrs2])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.s], message2).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message2, oneSignature2).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)
|
||||
const oneSignature3 = packSignatures([vrs3])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs3.v], [vrs3.r], [vrs3.s], message3).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridge.executeSignatures(message3, oneSignature3).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
})
|
||||
describe('#withdraw with 2 minimum signatures', async () => {
|
||||
|
@ -386,22 +396,18 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridgeWithMultiSignatures.address)
|
||||
const signature = await sign(twoAuthorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridgeWithMultiSignatures.relayedMessages(transactionHash))
|
||||
|
||||
await foreignBridgeWithMultiSignatures
|
||||
.executeSignatures([vrs.v], [vrs.r], [vrs.s], message)
|
||||
.should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridgeWithMultiSignatures.executeSignatures(message, oneSignature).should.be.rejectedWith(ERROR_MSG)
|
||||
|
||||
// msg 2
|
||||
const signature2 = await sign(twoAuthorities[1], message)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
const twoSignatures = packSignatures([vrs, vrs2])
|
||||
|
||||
const { logs } = await foreignBridgeWithMultiSignatures.executeSignatures(
|
||||
[vrs.v, vrs2.v],
|
||||
[vrs.r, vrs2.r],
|
||||
[vrs.s, vrs2.s],
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const { logs } = await foreignBridgeWithMultiSignatures.executeSignatures(message, twoSignatures).should.be
|
||||
.fulfilled
|
||||
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipientAccount)
|
||||
|
@ -415,11 +421,10 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridgeWithMultiSignatures.address)
|
||||
const signature = await sign(twoAuthorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const twoSignatures = packSignatures([vrs, vrs])
|
||||
false.should.be.equal(await foreignBridgeWithMultiSignatures.relayedMessages(transactionHash))
|
||||
|
||||
await foreignBridgeWithMultiSignatures
|
||||
.executeSignatures([vrs.v, vrs.v], [vrs.r, vrs.r], [vrs.s, vrs.s], message)
|
||||
.should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridgeWithMultiSignatures.executeSignatures(message, twoSignatures).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
it('works with 5 validators and 3 required signatures', async () => {
|
||||
const recipient = accounts[8]
|
||||
|
@ -459,12 +464,9 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const signature3 = await sign(authoritiesFiveAccs[2], message)
|
||||
const vrs3 = signatureToVRS(signature3)
|
||||
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(
|
||||
[vrs.v, vrs2.v, vrs3.v],
|
||||
[vrs.r, vrs2.r, vrs3.r],
|
||||
[vrs.s, vrs2.s, vrs3.s],
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
|
||||
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(message, threeSignatures).should.be.fulfilled
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipient)
|
||||
logs[0].args.value.should.be.bignumber.equal(value)
|
||||
|
@ -504,12 +506,9 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
vrsList[i] = signatureToVRS(signature)
|
||||
}
|
||||
|
||||
const { receipt } = await foreignBridgeWithMaxSigs.executeSignatures(
|
||||
vrsList.map(vrs => vrs.v),
|
||||
vrsList.map(vrs => vrs.r),
|
||||
vrsList.map(vrs => vrs.s),
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const maxSignatures = packSignatures(vrsList)
|
||||
|
||||
const { receipt } = await foreignBridgeWithMaxSigs.executeSignatures(message, maxSignatures).should.be.fulfilled
|
||||
expect(receipt.gasUsed).to.be.lte(MAX_GAS)
|
||||
})
|
||||
})
|
||||
|
@ -653,9 +652,10 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const message = createMessage(recipientAccount, valueOnHome, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
|
||||
const { logs } = await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipientAccount)
|
||||
|
@ -707,12 +707,10 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const signature2 = await sign(twoAuthorities[1], message)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
|
||||
const { logs } = await foreignBridgeWithMultiSignatures.executeSignatures(
|
||||
[vrs.v, vrs2.v],
|
||||
[vrs.r, vrs2.r],
|
||||
[vrs.s, vrs2.s],
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const twoSignatures = packSignatures([vrs, vrs2])
|
||||
|
||||
const { logs } = await foreignBridgeWithMultiSignatures.executeSignatures(message, twoSignatures).should.be
|
||||
.fulfilled
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipient)
|
||||
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
|
||||
|
@ -1249,9 +1247,10 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
expect(await foreignBridge.relayedMessages(transactionHash)).to.be.equal(false)
|
||||
|
||||
const { logs } = await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
|
||||
expectEventInLogs(logs, 'RelayedMessage', {
|
||||
recipient: recipientAccount,
|
||||
|
|
|
@ -33,18 +33,7 @@ function strip0x(input) {
|
|||
module.exports.strip0x = strip0x
|
||||
|
||||
// extracts and returns the `v`, `r` and `s` values from a `signature`.
|
||||
// all inputs and outputs are hex strings with leading '0x'.
|
||||
function signatureToVRS(rawSignature) {
|
||||
assert.equal(rawSignature.length, 2 + 32 * 2 + 32 * 2 + 2)
|
||||
const signature = strip0x(rawSignature)
|
||||
const v = parseInt(signature.substr(64 * 2), 16)
|
||||
const r = `0x${signature.substr(0, 32 * 2)}`
|
||||
const s = `0x${signature.substr(32 * 2, 32 * 2)}`
|
||||
return { v, r, s }
|
||||
}
|
||||
module.exports.signatureToVRS = signatureToVRS
|
||||
|
||||
function signatureToVRSAMB(rawSignature) {
|
||||
assert.equal(rawSignature.length, 2 + 32 * 2 + 32 * 2 + 2)
|
||||
const signature = strip0x(rawSignature)
|
||||
const v = signature.substr(64 * 2)
|
||||
|
@ -52,7 +41,7 @@ function signatureToVRSAMB(rawSignature) {
|
|||
const s = signature.substr(32 * 2, 32 * 2)
|
||||
return { v, r, s }
|
||||
}
|
||||
module.exports.signatureToVRSAMB = signatureToVRSAMB
|
||||
module.exports.signatureToVRS = signatureToVRS
|
||||
|
||||
function packSignatures(array) {
|
||||
const length = strip0x(web3.utils.toHex(array.length))
|
||||
|
|
|
@ -18,7 +18,8 @@ const {
|
|||
ether,
|
||||
expectEventInLogs,
|
||||
createAccounts,
|
||||
createFullAccounts
|
||||
createFullAccounts,
|
||||
packSignatures
|
||||
} = require('../helpers/helpers')
|
||||
|
||||
const oneEther = ether('1')
|
||||
|
@ -206,8 +207,9 @@ contract('ForeignBridge', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
const { logs } = await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).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)
|
||||
|
@ -226,8 +228,9 @@ contract('ForeignBridge', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, accounts[0])
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridge.executeSignatures(message, oneSignature).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
it('should allow second deposit with different transactionHash but same recipient and value', async () => {
|
||||
const recipientAccount = accounts[3]
|
||||
|
@ -238,15 +241,17 @@ contract('ForeignBridge', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
// tx 2
|
||||
const transactionHash2 = '0x77a496628a776a03d58d7e6059a5937f04bebd8ba4ff89f76dd4bb8ba7e291ee'
|
||||
const message2 = createMessage(recipientAccount, value, transactionHash2, foreignBridge.address)
|
||||
const signature2 = await sign(authorities[0], message2)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
const oneSignature2 = packSignatures([vrs2])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash2))
|
||||
const { logs } = await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.s], message2).should.be.fulfilled
|
||||
const { logs } = await foreignBridge.executeSignatures(message2, oneSignature2).should.be.fulfilled
|
||||
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipientAccount)
|
||||
|
@ -268,14 +273,16 @@ contract('ForeignBridge', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
// tx 2
|
||||
const message2 = createMessage(accounts[4], value, transactionHash, foreignBridge.address)
|
||||
const signature2 = await sign(authorities[0], message2)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
const oneSignature2 = packSignatures([vrs2])
|
||||
true.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
|
||||
await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.s], message2).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridge.executeSignatures(message2, oneSignature2).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
|
||||
it('should not allow withdraw over home max tx limit', async () => {
|
||||
|
@ -286,8 +293,9 @@ contract('ForeignBridge', async accounts => {
|
|||
const message = createMessage(recipientAccount, invalidValue, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridge.executeSignatures(message, oneSignature).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
|
||||
it('should not allow withdraw over daily home limit', async () => {
|
||||
|
@ -297,22 +305,25 @@ contract('ForeignBridge', async accounts => {
|
|||
const message = createMessage(recipientAccount, halfEther, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message, oneSignature).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)
|
||||
const oneSignature2 = packSignatures([vrs2])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.s], message2).should.be.fulfilled
|
||||
await foreignBridge.executeSignatures(message2, oneSignature2).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)
|
||||
const oneSignature3 = packSignatures([vrs3])
|
||||
|
||||
await foreignBridge.executeSignatures([vrs3.v], [vrs3.r], [vrs3.s], message3).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridge.executeSignatures(message3, oneSignature3).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -352,19 +363,15 @@ contract('ForeignBridge', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridgeWithMultiSignatures.address)
|
||||
const signature = await sign(twoAuthorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
false.should.be.equal(await foreignBridgeWithMultiSignatures.relayedMessages(transactionHash))
|
||||
await foreignBridgeWithMultiSignatures
|
||||
.executeSignatures([vrs.v], [vrs.r], [vrs.s], message)
|
||||
.should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridgeWithMultiSignatures.executeSignatures(message, oneSignature).should.be.rejectedWith(ERROR_MSG)
|
||||
// msg 2
|
||||
const signature2 = await sign(twoAuthorities[1], message)
|
||||
const vrs2 = signatureToVRS(signature2)
|
||||
const { logs } = await foreignBridgeWithMultiSignatures.executeSignatures(
|
||||
[vrs.v, vrs2.v],
|
||||
[vrs.r, vrs2.r],
|
||||
[vrs.s, vrs2.s],
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const twoSignatures = packSignatures([vrs, vrs2])
|
||||
const { logs } = await foreignBridgeWithMultiSignatures.executeSignatures(message, twoSignatures).should.be
|
||||
.fulfilled
|
||||
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipientAccount)
|
||||
|
@ -380,10 +387,9 @@ contract('ForeignBridge', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridgeWithMultiSignatures.address)
|
||||
const signature = await sign(twoAuthorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const twoSignatures = packSignatures([vrs, vrs])
|
||||
false.should.be.equal(await foreignBridgeWithMultiSignatures.relayedMessages(transactionHash))
|
||||
await foreignBridgeWithMultiSignatures
|
||||
.executeSignatures([vrs.v, vrs.v], [vrs.r, vrs.r], [vrs.s, vrs.s], message)
|
||||
.should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridgeWithMultiSignatures.executeSignatures(message, twoSignatures).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
it('works with 5 validators and 3 required signatures', async () => {
|
||||
const recipient = accounts[8]
|
||||
|
@ -423,12 +429,9 @@ contract('ForeignBridge', async accounts => {
|
|||
const signature3 = await sign(authoritiesFiveAccs[2], message)
|
||||
const vrs3 = signatureToVRS(signature3)
|
||||
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(
|
||||
[vrs.v, vrs2.v, vrs3.v],
|
||||
[vrs.r, vrs2.r, vrs3.r],
|
||||
[vrs.s, vrs2.s, vrs3.s],
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const thressSignature = packSignatures([vrs, vrs2, vrs3])
|
||||
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(message, thressSignature).should.be.fulfilled
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipient)
|
||||
logs[0].args.value.should.be.bignumber.equal(value)
|
||||
|
@ -468,15 +471,12 @@ contract('ForeignBridge', async accounts => {
|
|||
vrsList[i] = signatureToVRS(signature)
|
||||
}
|
||||
|
||||
const { receipt } = await foreignBridgeWithMaxSigs.executeSignatures(
|
||||
vrsList.map(vrs => vrs.v),
|
||||
vrsList.map(vrs => vrs.r),
|
||||
vrsList.map(vrs => vrs.s),
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const maxSignatures = packSignatures(vrsList)
|
||||
|
||||
const { receipt } = await foreignBridgeWithMaxSigs.executeSignatures(message, maxSignatures).should.be.fulfilled
|
||||
expect(receipt.gasUsed).to.be.lte(MAX_GAS)
|
||||
})
|
||||
it('Should fail if length of signatures is not equal', async () => {
|
||||
it('Should fail if length of signatures is wrong', async () => {
|
||||
const recipient = accounts[8]
|
||||
const authoritiesFiveAccs = [accounts[1], accounts[2], accounts[3], accounts[4], accounts[5]]
|
||||
const ownerOfValidators = accounts[0]
|
||||
|
@ -513,15 +513,12 @@ contract('ForeignBridge', async accounts => {
|
|||
// signature 3
|
||||
const signature3 = await sign(authoritiesFiveAccs[2], message)
|
||||
const vrs3 = signatureToVRS(signature3)
|
||||
|
||||
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
|
||||
await foreignBridgeWithThreeSigs
|
||||
.executeSignatures([vrs.v, vrs2.v], [vrs.r], [vrs.s, vrs2.s, vrs3.s], message)
|
||||
.executeSignatures(message, `0x04${threeSignatures.slice(4)}`)
|
||||
.should.be.rejectedWith(ERROR_MSG)
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(
|
||||
[vrs.v, vrs2.v, vrs3.v],
|
||||
[vrs.r, vrs2.r, vrs3.r],
|
||||
[vrs.s, vrs2.s, vrs3.s],
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(message, threeSignatures).should.be.fulfilled
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipient)
|
||||
logs[0].args.value.should.be.bignumber.equal(value)
|
||||
|
@ -1233,8 +1230,9 @@ contract('ForeignBridge', async accounts => {
|
|||
const message = createMessage(recipientAccount, value, transactionHash, foreignBridge.address)
|
||||
const signature = await sign(validators[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const oneSignature = packSignatures([vrs])
|
||||
|
||||
const { logs } = await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
|
||||
logs[0].event.should.be.equal('FeeDistributedFromSignatures')
|
||||
logs[0].args.feeAmount.should.be.bignumber.equal(feeAmount)
|
||||
|
@ -1301,13 +1299,10 @@ contract('ForeignBridge', async accounts => {
|
|||
const vrs2 = signatureToVRS(signature2)
|
||||
const vrs3 = signatureToVRS(signature3)
|
||||
|
||||
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
|
||||
|
||||
// When
|
||||
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
|
||||
const { logs } = await foreignBridge.executeSignatures(message, threeSignatures).should.be.fulfilled
|
||||
|
||||
// Then
|
||||
logs[0].event.should.be.equal('FeeDistributedFromSignatures')
|
||||
|
@ -1390,13 +1385,10 @@ contract('ForeignBridge', async accounts => {
|
|||
const vrs2 = signatureToVRS(signature2)
|
||||
const vrs3 = signatureToVRS(signature3)
|
||||
|
||||
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
|
||||
|
||||
// When
|
||||
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
|
||||
const { logs } = await foreignBridge.executeSignatures(message, threeSignatures).should.be.fulfilled
|
||||
|
||||
// Then
|
||||
logs[0].event.should.be.equal('FeeDistributedFromSignatures')
|
||||
|
@ -1458,8 +1450,10 @@ contract('ForeignBridge', async accounts => {
|
|||
const signature = await sign(validators[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
|
||||
const oneSignature = packSignatures([vrs])
|
||||
|
||||
// When
|
||||
const { receipt } = await foreignBridge.executeSignatures([vrs.v], [vrs.r], [vrs.s], message).should.be.fulfilled
|
||||
const { receipt } = await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
|
||||
expect(receipt.gasUsed).to.be.lte(MAX_GAS)
|
||||
})
|
||||
})
|
||||
|
@ -1505,12 +1499,9 @@ contract('ForeignBridge', async accounts => {
|
|||
const signature3 = await sign(authoritiesFiveAccs[2], message)
|
||||
const vrs3 = signatureToVRS(signature3)
|
||||
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(
|
||||
[vrs.v, vrs2.v, vrs3.v],
|
||||
[vrs.r, vrs2.r, vrs3.r],
|
||||
[vrs.s, vrs2.s, vrs3.s],
|
||||
message
|
||||
).should.be.fulfilled
|
||||
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
|
||||
|
||||
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(message, threeSignatures).should.be.fulfilled
|
||||
logs[0].event.should.be.equal('RelayedMessage')
|
||||
logs[0].args.recipient.should.be.equal(recipient)
|
||||
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
|
||||
|
|
Loading…
Reference in New Issue