Used more convinient uintX types for numbers in contracts
This commit is contained in:
parent
5efe01db65
commit
93563cfa8a
|
@ -3,26 +3,26 @@ pragma solidity ^0.5.0;
|
|||
import './openzeppelin-solidity/contracts/token/ERC20/IERC20.sol';
|
||||
|
||||
contract BasicBridge {
|
||||
uint constant UPPER_BOUND = uint(-1);
|
||||
uint32 constant UPPER_BOUND = 0xffffffff;
|
||||
|
||||
event EpochEnd(uint indexed epoch);
|
||||
event EpochClose(uint indexed epoch);
|
||||
event EpochEnd(uint16 indexed epoch);
|
||||
event EpochClose(uint16 indexed epoch);
|
||||
event ForceSign();
|
||||
event NewEpoch(uint indexed oldEpoch, uint indexed newEpoch);
|
||||
event NewEpochCancelled(uint indexed epoch);
|
||||
event NewFundsTransfer(uint indexed oldEpoch, uint indexed newEpoch);
|
||||
event EpochStart(uint indexed epoch, uint x, uint y);
|
||||
event NewEpoch(uint16 indexed oldEpoch, uint16 indexed newEpoch);
|
||||
event NewEpochCancelled(uint16 indexed epoch);
|
||||
event NewFundsTransfer(uint16 indexed oldEpoch, uint16 indexed newEpoch);
|
||||
event EpochStart(uint16 indexed epoch, uint x, uint y);
|
||||
|
||||
struct State {
|
||||
address[] validators;
|
||||
uint threshold;
|
||||
uint rangeSize;
|
||||
uint startBlock;
|
||||
uint endBlock;
|
||||
uint nonce;
|
||||
uint32 startBlock;
|
||||
uint32 endBlock;
|
||||
uint32 nonce;
|
||||
uint16 threshold;
|
||||
uint16 rangeSize;
|
||||
bool closeEpoch;
|
||||
uint x;
|
||||
uint y;
|
||||
bool closeEpoch;
|
||||
}
|
||||
|
||||
enum Status {
|
||||
|
@ -33,15 +33,15 @@ contract BasicBridge {
|
|||
FUNDS_TRANSFER // funds transfer, cannot be cancelled
|
||||
}
|
||||
|
||||
mapping(uint => State) states;
|
||||
mapping(uint16 => State) public states;
|
||||
|
||||
Status public status;
|
||||
|
||||
uint public epoch;
|
||||
uint public nextEpoch;
|
||||
uint16 public epoch;
|
||||
uint16 public nextEpoch;
|
||||
|
||||
uint minTxLimit;
|
||||
uint maxTxLimit;
|
||||
uint96 minTxLimit;
|
||||
uint96 maxTxLimit;
|
||||
|
||||
IERC20 public tokenContract;
|
||||
|
||||
|
@ -55,21 +55,11 @@ contract BasicBridge {
|
|||
_;
|
||||
}
|
||||
|
||||
modifier readyOrClosing {
|
||||
require(status == Status.READY || status == Status.CLOSING_EPOCH, "Not in ready or closing epoch state");
|
||||
_;
|
||||
}
|
||||
|
||||
modifier voting {
|
||||
require(status == Status.VOTING, "Not in voting state");
|
||||
_;
|
||||
}
|
||||
|
||||
modifier readyOrVoting {
|
||||
require(status == Status.READY || status == Status.VOTING, "Not in ready or voting state");
|
||||
_;
|
||||
}
|
||||
|
||||
modifier keygen {
|
||||
require(status == Status.KEYGEN, "Not in keygen state");
|
||||
_;
|
||||
|
@ -80,60 +70,55 @@ contract BasicBridge {
|
|||
_;
|
||||
}
|
||||
|
||||
modifier currentValidator {
|
||||
require(getPartyId() != 0, "Not a current validator");
|
||||
_;
|
||||
}
|
||||
|
||||
function getParties() view public returns (uint) {
|
||||
function getParties() view public returns (uint16) {
|
||||
return getParties(epoch);
|
||||
}
|
||||
|
||||
function getNextParties() view public returns (uint) {
|
||||
function getNextParties() view public returns (uint16) {
|
||||
return getParties(nextEpoch);
|
||||
}
|
||||
|
||||
function getParties(uint _epoch) view public returns (uint) {
|
||||
return states[_epoch].validators.length;
|
||||
function getParties(uint16 _epoch) view public returns (uint16) {
|
||||
return uint16(states[_epoch].validators.length);
|
||||
}
|
||||
|
||||
function getThreshold() view public returns (uint) {
|
||||
function getThreshold() view public returns (uint16) {
|
||||
return getThreshold(epoch);
|
||||
}
|
||||
|
||||
function getNextThreshold() view public returns (uint) {
|
||||
function getNextThreshold() view public returns (uint16) {
|
||||
return getThreshold(nextEpoch);
|
||||
}
|
||||
|
||||
function getThreshold(uint _epoch) view public returns (uint) {
|
||||
function getThreshold(uint16 _epoch) view public returns (uint16) {
|
||||
return states[_epoch].threshold;
|
||||
}
|
||||
|
||||
function getStartBlock() view public returns (uint) {
|
||||
function getStartBlock() view public returns (uint32) {
|
||||
return getStartBlock(epoch);
|
||||
}
|
||||
|
||||
function getStartBlock(uint _epoch) view public returns (uint) {
|
||||
function getStartBlock(uint16 _epoch) view public returns (uint32) {
|
||||
return states[_epoch].startBlock;
|
||||
}
|
||||
|
||||
function getRangeSize() view public returns (uint) {
|
||||
function getRangeSize() view public returns (uint16) {
|
||||
return getRangeSize(epoch);
|
||||
}
|
||||
|
||||
function getNextRangeSize() view public returns (uint) {
|
||||
function getNextRangeSize() view public returns (uint16) {
|
||||
return getRangeSize(nextEpoch);
|
||||
}
|
||||
|
||||
function getRangeSize(uint _epoch) view public returns (uint) {
|
||||
function getRangeSize(uint16 _epoch) view public returns (uint16) {
|
||||
return states[_epoch].rangeSize;
|
||||
}
|
||||
|
||||
function getNonce() view public returns (uint) {
|
||||
function getNonce() view public returns (uint32) {
|
||||
return getNonce(epoch);
|
||||
}
|
||||
|
||||
function getNonce(uint _epoch) view public returns (uint) {
|
||||
function getNonce(uint16 _epoch) view public returns (uint32) {
|
||||
return states[_epoch].nonce;
|
||||
}
|
||||
|
||||
|
@ -153,24 +138,24 @@ contract BasicBridge {
|
|||
return getCloseEpoch(nextEpoch);
|
||||
}
|
||||
|
||||
function getCloseEpoch(uint _epoch) view public returns (bool) {
|
||||
function getCloseEpoch(uint16 _epoch) view public returns (bool) {
|
||||
return states[_epoch].closeEpoch;
|
||||
}
|
||||
|
||||
function getPartyId() view public returns (uint) {
|
||||
function getPartyId() view public returns (uint16) {
|
||||
address[] memory validators = getValidators();
|
||||
for (uint i = 0; i < getParties(); i++) {
|
||||
if (validators[i] == msg.sender)
|
||||
return i + 1;
|
||||
return uint16(i + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getNextPartyId(address a) view public returns (uint) {
|
||||
function getNextPartyId(address a) view public returns (uint16) {
|
||||
address[] memory validators = getNextValidators();
|
||||
for (uint i = 0; i < getNextParties(); i++) {
|
||||
if (validators[i] == a)
|
||||
return i + 1;
|
||||
return uint16(i + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -183,7 +168,7 @@ contract BasicBridge {
|
|||
return getValidators(nextEpoch);
|
||||
}
|
||||
|
||||
function getValidators(uint _epoch) view public returns (address[] memory) {
|
||||
function getValidators(uint16 _epoch) view public returns (address[] memory) {
|
||||
return states[_epoch].validators;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,16 @@ import './openzeppelin-solidity/contracts/token/ERC20/IERC20.sol';
|
|||
import "./MessageHandler.sol";
|
||||
|
||||
contract Bridge is MessageHandler {
|
||||
event ExchangeRequest(uint value, uint nonce);
|
||||
event ExchangeRequest(uint96 value, uint32 nonce);
|
||||
|
||||
mapping(bytes32 => bool) usedExchangeRanges;
|
||||
|
||||
constructor(
|
||||
uint threshold,
|
||||
uint16 threshold,
|
||||
address[] memory validators,
|
||||
address _tokenContract,
|
||||
uint[2] memory limits,
|
||||
uint rangeSize,
|
||||
uint96[2] memory limits,
|
||||
uint16 rangeSize,
|
||||
bool closeEpoch
|
||||
) public {
|
||||
require(validators.length > 0);
|
||||
|
@ -43,10 +43,10 @@ contract Bridge is MessageHandler {
|
|||
emit NewEpoch(0, 1);
|
||||
}
|
||||
|
||||
function exchange(uint value) public ready {
|
||||
function exchange(uint96 value) public ready {
|
||||
require(value >= minTxLimit && value >= 10 ** 10 && value <= maxTxLimit);
|
||||
|
||||
uint txRange = (block.number - getStartBlock()) / getRangeSize();
|
||||
uint32 txRange = (uint32(block.number) - getStartBlock()) / uint32(getRangeSize());
|
||||
if (!usedExchangeRanges[keccak256(abi.encodePacked(txRange, epoch))]) {
|
||||
usedExchangeRanges[keccak256(abi.encodePacked(txRange, epoch))] = true;
|
||||
states[epoch].nonce++;
|
||||
|
|
|
@ -24,7 +24,7 @@ contract Government is BasicBridge {
|
|||
states[nextEpoch].nonce = UPPER_BOUND;
|
||||
if (nextEpoch == 1) {
|
||||
status = Status.READY;
|
||||
states[nextEpoch].startBlock = block.number;
|
||||
states[nextEpoch].startBlock = uint32(block.number);
|
||||
epoch = nextEpoch;
|
||||
emit EpochStart(epoch, x, y);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ contract Government is BasicBridge {
|
|||
require(epoch > 0, "First epoch does not need funds transfer");
|
||||
|
||||
status = Status.READY;
|
||||
states[nextEpoch].startBlock = block.number;
|
||||
states[nextEpoch].startBlock = uint32(block.number);
|
||||
epoch = nextEpoch;
|
||||
emit EpochStart(epoch, getX(), getY());
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ contract Government is BasicBridge {
|
|||
}
|
||||
|
||||
function _startVoting() internal ready {
|
||||
states[epoch].endBlock = block.number;
|
||||
states[epoch].endBlock = uint32(block.number);
|
||||
nextEpoch++;
|
||||
states[nextEpoch].threshold = getThreshold();
|
||||
states[nextEpoch].validators = getValidators();
|
||||
|
@ -76,23 +76,24 @@ contract Government is BasicBridge {
|
|||
function _removeValidator(address validator) internal voting {
|
||||
require(getNextPartyId(validator) != 0, "Already not a validator");
|
||||
|
||||
for (uint i = 0; i < getNextParties() - 1; i++) {
|
||||
uint16 lastPartyId = getNextParties() - 1;
|
||||
for (uint i = 0; i < lastPartyId; i++) {
|
||||
if (states[nextEpoch].validators[i] == validator) {
|
||||
states[nextEpoch].validators[i] = getNextValidators()[getNextParties() - 1];
|
||||
states[nextEpoch].validators[i] = getNextValidators()[lastPartyId];
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete states[nextEpoch].validators[getNextParties() - 1];
|
||||
delete states[nextEpoch].validators[lastPartyId];
|
||||
states[nextEpoch].validators.length--;
|
||||
}
|
||||
|
||||
function _changeThreshold(uint threshold) internal voting {
|
||||
function _changeThreshold(uint16 threshold) internal voting {
|
||||
require(threshold > 0, "Invalid threshold value");
|
||||
|
||||
states[nextEpoch].threshold = threshold;
|
||||
}
|
||||
|
||||
function _changeRangeSize(uint rangeSize) internal voting {
|
||||
function _changeRangeSize(uint16 rangeSize) internal voting {
|
||||
require(rangeSize > 0, "Invalid range size");
|
||||
|
||||
states[nextEpoch].rangeSize = rangeSize;
|
||||
|
@ -116,7 +117,7 @@ contract Government is BasicBridge {
|
|||
emit NewEpochCancelled(nextEpoch);
|
||||
}
|
||||
|
||||
function _transfer(address to, uint value) internal {
|
||||
function _transfer(address to, uint96 value) internal {
|
||||
if (tokenContract.balanceOf(address(this)) >= value) {
|
||||
tokenContract.transfer(to, value);
|
||||
} else {
|
||||
|
|
|
@ -3,37 +3,37 @@ pragma solidity ^0.5.0;
|
|||
|
||||
contract MessageDecoder {
|
||||
// [0] - action type
|
||||
// [1..32] - epoch
|
||||
// [33..] - payload
|
||||
function _decodeNumber(bytes memory message) pure internal returns (uint a) {
|
||||
// [1,2] - epoch
|
||||
// [3..] - payload
|
||||
function _decodeUint16(bytes memory message) pure internal returns (uint16 a) {
|
||||
assembly {
|
||||
a := mload(add(message, 65))
|
||||
a := mload(add(message, 5))
|
||||
}
|
||||
}
|
||||
|
||||
function _decodeBoolean(bytes memory message) pure internal returns (bool a) {
|
||||
assembly {
|
||||
a := and(mload(add(message, 34)), 1)
|
||||
a := and(mload(add(message, 4)), 1)
|
||||
}
|
||||
}
|
||||
|
||||
function _decodeAddress(bytes memory message) pure internal returns (address a) {
|
||||
assembly {
|
||||
a := mload(add(message, 53))
|
||||
a := mload(add(message, 23))
|
||||
}
|
||||
}
|
||||
|
||||
function _decodeKeygen(bytes memory message) pure internal returns (uint a, uint b) {
|
||||
assembly {
|
||||
a := mload(add(message, 65))
|
||||
b := mload(add(message, 97))
|
||||
a := mload(add(message, 35))
|
||||
b := mload(add(message, 67))
|
||||
}
|
||||
}
|
||||
|
||||
function _decodeTransfer(bytes memory message) pure internal returns (address a, uint b) {
|
||||
function _decodeTransfer(bytes memory message) pure internal returns (address a, uint96 b) {
|
||||
assembly {
|
||||
a := mload(add(message, 85))
|
||||
b := mload(add(message, 117))
|
||||
a := mload(add(message, 55))
|
||||
b := mload(add(message, 67))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ contract MessageHandler is Government, MessageDecoder {
|
|||
mapping(bytes32 => bool) public handledMessages;
|
||||
|
||||
function applyMessage(bytes memory message, bytes memory signatures) public {
|
||||
(bytes32 msgHash, uint msgEpoch) = checkSignedMessage(message, signatures);
|
||||
(bytes32 msgHash, uint16 msgEpoch) = checkSignedMessage(message, signatures);
|
||||
handledMessages[msgHash] = true;
|
||||
|
||||
Action msgAction = Action(uint8(message[0]));
|
||||
|
@ -23,77 +23,78 @@ contract MessageHandler is Government, MessageDecoder {
|
|||
}
|
||||
|
||||
if (msgAction == Action.CONFIRM_KEYGEN) {
|
||||
require(message.length == 97, "Incorrect message length");
|
||||
// [3,34] - x, [35,66] - y
|
||||
require(message.length == 67, "Incorrect message length");
|
||||
(uint x, uint y) = _decodeKeygen(message);
|
||||
_confirmKeygen(x, y);
|
||||
} else if (msgAction == Action.CONFIRM_FUNDS_TRANSFER) {
|
||||
require(message.length == 33, "Incorrect message length");
|
||||
require(message.length == 3, "Incorrect message length");
|
||||
_confirmFundsTransfer();
|
||||
} else if (msgAction == Action.CONFIRM_CLOSE_EPOCH) {
|
||||
require(message.length == 33, "Incorrect message length");
|
||||
require(message.length == 3, "Incorrect message length");
|
||||
_confirmCloseEpoch();
|
||||
} else if (msgAction == Action.VOTE_START_VOTING) {
|
||||
require(message.length == 33, "Incorrect message length");
|
||||
require(message.length == 3, "Incorrect message length");
|
||||
_startVoting();
|
||||
} else if (msgAction == Action.VOTE_ADD_VALIDATOR) {
|
||||
require(message.length == 53, "Incorrect message length");
|
||||
// [3,22] - address, [23,31] - extra data
|
||||
require(message.length == 32, "Incorrect message length");
|
||||
address validator = _decodeAddress(message);
|
||||
_addValidator(validator);
|
||||
} else if (msgAction == Action.VOTE_REMOVE_VALIDATOR) {
|
||||
require(message.length == 53, "Incorrect message length");
|
||||
// [3,22] - address, [23,31] - extra data
|
||||
require(message.length == 32, "Incorrect message length");
|
||||
address validator = _decodeAddress(message);
|
||||
_removeValidator(validator);
|
||||
} else if (msgAction == Action.VOTE_CHANGE_THRESHOLD) {
|
||||
require(message.length == 65, "Incorrect message length");
|
||||
uint threshold = _decodeNumber(message);
|
||||
// [3,4] - threshold, [5,31] - extra data
|
||||
require(message.length == 32, "Incorrect message length");
|
||||
uint16 threshold = _decodeUint16(message);
|
||||
_changeThreshold(threshold);
|
||||
} else if (msgAction == Action.VOTE_CHANGE_RANGE_SIZE) {
|
||||
require(message.length == 65, "Incorrect message length");
|
||||
uint rangeSize = _decodeNumber(message);
|
||||
// [3,4] - rangeSize, [5,31] - extra data
|
||||
require(message.length == 32, "Incorrect message length");
|
||||
uint16 rangeSize = _decodeUint16(message);
|
||||
_changeRangeSize(rangeSize);
|
||||
} else if (msgAction == Action.VOTE_CHANGE_CLOSE_EPOCH) {
|
||||
require(message.length == 34, "Incorrect message length");
|
||||
// [3] - closeEpoch, [4,31] - extra data
|
||||
require(message.length == 32, "Incorrect message length");
|
||||
bool closeEpoch = _decodeBoolean(message);
|
||||
_changeCloseEpoch(closeEpoch);
|
||||
} else if (msgAction == Action.VOTE_START_KEYGEN) {
|
||||
require(message.length == 33, "Incorrect message length");
|
||||
require(message.length == 3, "Incorrect message length");
|
||||
_startKeygen();
|
||||
} else if (msgAction == Action.VOTE_CANCEL_KEYGEN) {
|
||||
require(message.length == 33, "Incorrect message length");
|
||||
require(message.length == 3, "Incorrect message length");
|
||||
_cancelKeygen();
|
||||
} else if (msgAction == Action.TRANSFER) {
|
||||
require(message.length == 117, "Incorrect message length");
|
||||
(address to, uint value) = _decodeTransfer(message);
|
||||
// [3,34] - txHash, [35,54] - address, [55,66] - value
|
||||
require(message.length == 67, "Incorrect message length");
|
||||
(address to, uint96 value) = _decodeTransfer(message);
|
||||
_transfer(to, value);
|
||||
} else {
|
||||
revert("Unknown message action");
|
||||
}
|
||||
}
|
||||
|
||||
function checkSignedMessage(bytes memory message, bytes memory signatures) view public returns (bytes32, uint) {
|
||||
function checkSignedMessage(bytes memory message, bytes memory signatures) view public returns (bytes32, uint16) {
|
||||
require(signatures.length % SIGNATURE_SIZE == 0, "Incorrect signatures length");
|
||||
|
||||
bytes32 msgHash;
|
||||
if (message.length == 33) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n33", message));
|
||||
} else if (message.length == 34) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n34", message));
|
||||
} else if (message.length == 53) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n53", message));
|
||||
} else if (message.length == 65) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n65", message));
|
||||
} else if (message.length == 97) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n97", message));
|
||||
} else if (message.length == 117) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n117", message));
|
||||
if (message.length == 3) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n3", message));
|
||||
} else if (message.length == 32) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
|
||||
} else if (message.length == 67) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n67", message));
|
||||
} else {
|
||||
revert("Incorrect message length");
|
||||
}
|
||||
require(!handledMessages[msgHash], "Tx was already handled");
|
||||
|
||||
uint msgEpoch;
|
||||
uint16 msgEpoch;
|
||||
assembly {
|
||||
msgEpoch := mload(add(message, 33))
|
||||
msgEpoch := mload(add(message, 3))
|
||||
}
|
||||
require(msgEpoch <= nextEpoch, "Invalid epoch number");
|
||||
|
||||
|
|
|
@ -15,18 +15,12 @@ contract SignedMessageStorage {
|
|||
require(rsv.length == 65, "Incorrect signature length");
|
||||
|
||||
bytes32 msgHash;
|
||||
if (message.length == 33) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n33", message));
|
||||
} else if (message.length == 34) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n34", message));
|
||||
} else if (message.length == 53) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n53", message));
|
||||
} else if (message.length == 65) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n65", message));
|
||||
} else if (message.length == 97) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n97", message));
|
||||
} else if (message.length == 117) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n117", message));
|
||||
if (message.length == 3) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n3", message));
|
||||
} else if (message.length == 32) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
|
||||
} else if (message.length == 67) {
|
||||
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n67", message));
|
||||
} else {
|
||||
revert("Incorrect message length");
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
pragma solidity ^0.5.0;
|
||||
|
||||
contract SignupStorage {
|
||||
mapping(bytes32 => uint) public signupsCount;
|
||||
mapping(bytes32 => mapping(address => uint)) public signups;
|
||||
mapping(bytes32 => uint16) public signupsCount;
|
||||
mapping(bytes32 => mapping(address => uint16)) public signups;
|
||||
|
||||
function signup(bytes32 hash) public {
|
||||
require(signups[hash][msg.sender] == 0, "Already signuped");
|
||||
|
@ -14,12 +14,12 @@ contract SignupStorage {
|
|||
bytes32 hash,
|
||||
address[] memory validators,
|
||||
address validator
|
||||
) view public returns (uint) {
|
||||
) view public returns (uint16) {
|
||||
if (signups[hash][validator] == 0)
|
||||
return 0;
|
||||
uint id = 1;
|
||||
uint16 id = 1;
|
||||
for (uint i = 0; i < validators.length; i++) {
|
||||
uint vid = signups[hash][validators[i]];
|
||||
uint16 vid = signups[hash][validators[i]];
|
||||
if (vid > 0 && vid < signups[hash][validator])
|
||||
id++;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ contract SignupStorage {
|
|||
function getSignupAddress(
|
||||
bytes32 hash,
|
||||
address[] memory validators,
|
||||
uint signupNumber
|
||||
uint16 signupNumber
|
||||
) view public returns (address) {
|
||||
for (uint i = 0; i < validators.length; i++) {
|
||||
if (getSignupNumber(hash, validators, validators[i]) == signupNumber) {
|
||||
|
|
|
@ -7,8 +7,8 @@ const SIDE_MAX_FETCH_RANGE_SIZE = parseInt(process.env.SIDE_MAX_FETCH_RANGE_SIZE
|
|||
|
||||
const bridgeAbi = [
|
||||
'function applyMessage(bytes message, bytes signatures)',
|
||||
'function getThreshold(uint epoch) view returns (uint)',
|
||||
'function getValidators(uint epoch) view returns (address[])'
|
||||
'function getThreshold(uint16 epoch) view returns (uint16)',
|
||||
'function getValidators(uint16 epoch) view returns (address[])'
|
||||
]
|
||||
const sharedDbAbi = [
|
||||
'event NewMessage(bytes32 msgHash)',
|
||||
|
@ -31,7 +31,7 @@ async function delay(ms) {
|
|||
async function handleNewMessage(event) {
|
||||
const { msgHash } = event.values
|
||||
const message = await sharedDb.signedMessages(msgHash)
|
||||
const epoch = parseInt(message.slice(4, 68), 16)
|
||||
const epoch = parseInt(message.slice(4, 8), 16)
|
||||
const [threshold, validators] = await Promise.all([
|
||||
bridge.getThreshold(epoch),
|
||||
bridge.getValidators(epoch)
|
||||
|
@ -49,7 +49,8 @@ async function handleNewMessage(event) {
|
|||
gasLimit: 1000000,
|
||||
nonce
|
||||
})
|
||||
await tx.wait()
|
||||
const receipt = await tx.wait()
|
||||
console.log(`Used gas: ${receipt.gasUsed.toNumber()}`)
|
||||
nonce += 1
|
||||
break
|
||||
}
|
||||
|
@ -89,7 +90,7 @@ async function loop() {
|
|||
|
||||
for (let i = 0; i < bridgeEvents.length; i += 1) {
|
||||
const event = sharedDb.interface.parseLog(bridgeEvents[i])
|
||||
console.log('Consumed event', event, bridgeEvents[i])
|
||||
console.log('Consumed event', event)
|
||||
await handleNewMessage(event)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,17 +15,17 @@ const HOME_MAX_FETCH_RANGE_SIZE = parseInt(process.env.HOME_MAX_FETCH_RANGE_SIZE
|
|||
|
||||
const provider = new ethers.providers.JsonRpcProvider(HOME_RPC_URL)
|
||||
const bridgeAbi = [
|
||||
'event ExchangeRequest(uint value, uint nonce)',
|
||||
'event EpochEnd(uint indexed epoch)',
|
||||
'event NewEpoch(uint indexed oldEpoch, uint indexed newEpoch)',
|
||||
'event NewEpochCancelled(uint indexed epoch)',
|
||||
'event NewFundsTransfer(uint indexed oldEpoch, uint indexed newEpoch)',
|
||||
'event EpochStart(uint indexed epoch, uint x, uint y)',
|
||||
'event EpochClose(uint indexed epoch)',
|
||||
'event ExchangeRequest(uint96 value, uint32 nonce)',
|
||||
'event EpochEnd(uint16 indexed epoch)',
|
||||
'event NewEpoch(uint16 indexed oldEpoch, uint16 indexed newEpoch)',
|
||||
'event NewEpochCancelled(uint16 indexed epoch)',
|
||||
'event NewFundsTransfer(uint16 indexed oldEpoch, uint16 indexed newEpoch)',
|
||||
'event EpochStart(uint16 indexed epoch, uint256 x, uint256 y)',
|
||||
'event EpochClose(uint16 indexed epoch)',
|
||||
'event ForceSign()',
|
||||
'function getThreshold(uint epoch) view returns (uint)',
|
||||
'function getParties(uint epoch) view returns (uint)',
|
||||
'function getRangeSize() view returns (uint)',
|
||||
'function getThreshold(uint16 epoch) view returns (uint16)',
|
||||
'function getParties(uint16 epoch) view returns (uint16)',
|
||||
'function getRangeSize() view returns (uint16)',
|
||||
'function getValidators() view returns (address[])'
|
||||
]
|
||||
const bridge = new ethers.Contract(HOME_BRIDGE_ADDRESS, bridgeAbi, provider)
|
||||
|
@ -91,18 +91,18 @@ async function resetFutureMessages(queue) {
|
|||
}
|
||||
|
||||
async function sendKeygen(event) {
|
||||
const newEpoch = event.values.newEpoch.toNumber()
|
||||
const { newEpoch } = event.values
|
||||
keygenQueue.send({
|
||||
epoch: newEpoch,
|
||||
blockNumber,
|
||||
threshold: (await bridge.getThreshold(newEpoch)).toNumber(),
|
||||
parties: (await bridge.getParties(newEpoch)).toNumber()
|
||||
threshold: await bridge.getThreshold(newEpoch),
|
||||
parties: await bridge.getParties(newEpoch)
|
||||
})
|
||||
logger.debug('Sent keygen start event')
|
||||
}
|
||||
|
||||
function sendKeygenCancellation(event) {
|
||||
const eventEpoch = event.values.epoch.toNumber()
|
||||
const eventEpoch = event.values.epoch
|
||||
cancelKeygenQueue.send({
|
||||
epoch: eventEpoch,
|
||||
blockNumber
|
||||
|
@ -111,15 +111,14 @@ function sendKeygenCancellation(event) {
|
|||
}
|
||||
|
||||
async function sendSignFundsTransfer(event) {
|
||||
const newEpoch = event.values.newEpoch.toNumber()
|
||||
const oldEpoch = event.values.oldEpoch.toNumber()
|
||||
const { newEpoch, oldEpoch } = event.values
|
||||
signQueue.send({
|
||||
epoch: oldEpoch,
|
||||
blockNumber,
|
||||
newEpoch,
|
||||
nonce: foreignNonce[oldEpoch],
|
||||
threshold: (await bridge.getThreshold(oldEpoch)).toNumber(),
|
||||
parties: (await bridge.getParties(oldEpoch)).toNumber()
|
||||
threshold: await bridge.getThreshold(oldEpoch),
|
||||
parties: await bridge.getParties(oldEpoch)
|
||||
})
|
||||
logger.debug('Sent sign funds transfer event')
|
||||
foreignNonce[oldEpoch] += 1
|
||||
|
@ -150,7 +149,7 @@ async function sendSign(event, transactionHash) {
|
|||
y: publicKey.substr(68, 64)
|
||||
}),
|
||||
value: (new BN(event.values.value)).dividedBy(10 ** 18).toFixed(8, 3),
|
||||
nonce: event.values.nonce.toNumber()
|
||||
nonce: event.values.nonce
|
||||
}
|
||||
|
||||
exchangeQueue.send(msgToQueue)
|
||||
|
@ -166,18 +165,18 @@ async function sendStartSign() {
|
|||
epoch,
|
||||
blockNumber,
|
||||
nonce: foreignNonce[epoch],
|
||||
threshold: (await bridge.getThreshold(epoch)).toNumber(),
|
||||
parties: (await bridge.getParties(epoch)).toNumber()
|
||||
threshold: await bridge.getThreshold(epoch),
|
||||
parties: await bridge.getParties(epoch)
|
||||
})
|
||||
foreignNonce[epoch] += 1
|
||||
redisTx.incr(`foreignNonce${epoch}`)
|
||||
}
|
||||
|
||||
async function processEpochStart(event) {
|
||||
epoch = event.values.epoch.toNumber()
|
||||
epoch = event.values.epoch
|
||||
epochStart = blockNumber
|
||||
logger.info(`Epoch ${epoch} started`)
|
||||
rangeSize = (await bridge.getRangeSize()).toNumber()
|
||||
rangeSize = await bridge.getRangeSize()
|
||||
isCurrentValidator = (await bridge.getValidators()).includes(validatorAddress)
|
||||
if (isCurrentValidator) {
|
||||
logger.info(`${validatorAddress} is a current validator`)
|
||||
|
@ -194,8 +193,8 @@ async function sendEpochClose() {
|
|||
closeEpoch: epoch,
|
||||
blockNumber,
|
||||
nonce: foreignNonce[epoch],
|
||||
threshold: (await bridge.getThreshold(epoch)).toNumber(),
|
||||
parties: (await bridge.getParties(epoch)).toNumber()
|
||||
threshold: await bridge.getThreshold(epoch),
|
||||
parties: await bridge.getParties(epoch)
|
||||
})
|
||||
foreignNonce[epoch] += 1
|
||||
redisTx.incr(`foreignNonce${epoch}`)
|
||||
|
@ -220,7 +219,7 @@ async function initialize() {
|
|||
topics: bridge.filters.EpochStart().topics
|
||||
})).map((log) => bridge.interface.parseLog(log))
|
||||
|
||||
epoch = events.length ? events[events.length - 1].values.epoch.toNumber() : 0
|
||||
epoch = events.length ? events[events.length - 1].values.epoch : 0
|
||||
logger.info(`Current epoch ${epoch}`)
|
||||
epochStart = events.length ? events[events.length - 1].blockNumber : 1
|
||||
const saved = (parseInt(await redis.get('homeBlock'), 10) + 1) || parseInt(HOME_START_BLOCK, 10)
|
||||
|
@ -237,7 +236,7 @@ async function initialize() {
|
|||
blockNumber = saved
|
||||
foreignNonce[epoch] = parseInt(await redis.get(`foreignNonce${epoch}`), 10) || 0
|
||||
}
|
||||
rangeSize = (await bridge.getRangeSize()).toNumber()
|
||||
rangeSize = await bridge.getRangeSize()
|
||||
logger.debug(`Range size ${rangeSize}`)
|
||||
logger.debug('Checking if current validator')
|
||||
isCurrentValidator = (await bridge.getValidators()).includes(validatorAddress)
|
||||
|
|
|
@ -2,38 +2,28 @@ const tokenAbi = [
|
|||
'function balanceOf(address account) view returns (uint256)'
|
||||
]
|
||||
const bridgeAbi = [
|
||||
'function getX() view returns (uint)',
|
||||
'function getY() view returns (uint)',
|
||||
'function epoch() view returns (uint)',
|
||||
'function getRangeSize() view returns (uint)',
|
||||
'function getNextRangeSize() view returns (uint)',
|
||||
'function getStartBlock() view returns (uint)',
|
||||
'function getNonce() view returns (uint)',
|
||||
'function nextEpoch() view returns (uint)',
|
||||
'function getThreshold() view returns (uint)',
|
||||
'function getNextThreshold() view returns (uint)',
|
||||
'function getX() view returns (uint256)',
|
||||
'function getY() view returns (uint256)',
|
||||
'function epoch() view returns (uint16)',
|
||||
'function getRangeSize() view returns (uint16)',
|
||||
'function getNextRangeSize() view returns (uint16)',
|
||||
'function getStartBlock() view returns (uint32)',
|
||||
'function getNonce() view returns (uint16)',
|
||||
'function nextEpoch() view returns (uint16)',
|
||||
'function getThreshold() view returns (uint16)',
|
||||
'function getNextThreshold() view returns (uint16)',
|
||||
'function getValidators() view returns (address[])',
|
||||
'function getNextValidators() view returns (address[])',
|
||||
'function getCloseEpoch() view returns (bool)',
|
||||
'function getNextCloseEpoch() view returns (bool)',
|
||||
'function status() view returns (uint)',
|
||||
'function votesCount(bytes32) view returns (uint)',
|
||||
'function getNextPartyId(address a) view returns (uint)',
|
||||
'function confirmKeygen(uint x, uint y)',
|
||||
'function confirmFundsTransfer()',
|
||||
'function confirmCloseEpoch()',
|
||||
'function startVoting()',
|
||||
'function voteStartKeygen()',
|
||||
'function voteCancelKeygen()',
|
||||
'function voteAddValidator(address validator)',
|
||||
'function voteRemoveValidator(address validator)',
|
||||
'function voteChangeThreshold(uint threshold)',
|
||||
'function voteChangeCloseEpoch(bool closeEpoch)'
|
||||
'function status() view returns (uint8)',
|
||||
'function votesCount(bytes32) view returns (uint16)',
|
||||
'function getNextPartyId(address a) view returns (uint16)'
|
||||
]
|
||||
const sharedDbAbi = [
|
||||
'function getSignupAddress(bytes32 hash, address[] validators, uint signupNumber) view returns (address)',
|
||||
'function getSignupAddress(bytes32 hash, address[] validators, uint16 signupNumber) view returns (address)',
|
||||
'function getData(address from, bytes32 hash, bytes32 key) view returns (bytes)',
|
||||
'function getSignupNumber(bytes32 hash, address[] validators, address validator) view returns (uint)',
|
||||
'function getSignupNumber(bytes32 hash, address[] validators, address validator) view returns (uint16)',
|
||||
'function setData(bytes32 hash, bytes32 key, bytes data)',
|
||||
'function signup(bytes32 hash)',
|
||||
'function addSignature(bytes message, bytes rsv)',
|
||||
|
|
|
@ -6,7 +6,7 @@ const ethers = require('ethers')
|
|||
|
||||
const { tokenAbi, bridgeAbi, sharedDbAbi } = require('./contractsAbi')
|
||||
const {
|
||||
Ok, Err, decodeStatus, boundX
|
||||
Ok, Err, decodeStatus
|
||||
} = require('./utils')
|
||||
const encode = require('./encode')
|
||||
const decode = require('./decode')
|
||||
|
@ -128,8 +128,8 @@ async function set(req, res) {
|
|||
|
||||
async function signupKeygen(req, res) {
|
||||
logger.debug('SignupKeygen call')
|
||||
const epoch = (await bridge.nextEpoch()).toNumber()
|
||||
const partyId = (await bridge.getNextPartyId(validatorAddress)).toNumber()
|
||||
const epoch = await bridge.nextEpoch()
|
||||
const partyId = await bridge.getNextPartyId(validatorAddress)
|
||||
|
||||
if (partyId === 0) {
|
||||
res.send(Err({ message: 'Not a validator' }))
|
||||
|
@ -161,7 +161,7 @@ async function signupSign(req, res) {
|
|||
}
|
||||
|
||||
const validators = await bridge.getValidators()
|
||||
const id = (await sharedDb.getSignupNumber(hash, validators, validatorAddress)).toNumber()
|
||||
const id = await sharedDb.getSignupNumber(hash, validators, validatorAddress)
|
||||
|
||||
res.send(Ok({
|
||||
uuid: hash,
|
||||
|
@ -176,9 +176,9 @@ function encodeParam(param) {
|
|||
if (param.startsWith('0x')) {
|
||||
return Buffer.from(param.slice(2), 'hex')
|
||||
}
|
||||
return Buffer.from(padZeros(param, 64), 'hex')
|
||||
return Buffer.from(param, 'hex')
|
||||
case 'number':
|
||||
return Buffer.from(padZeros(new BN(param).toString(16), 64), 'hex')
|
||||
return Buffer.from(padZeros(param.toString(16), 4), 'hex')
|
||||
case 'boolean':
|
||||
return Buffer.from([param ? 1 : 0])
|
||||
default:
|
||||
|
@ -204,7 +204,7 @@ async function processMessage(message) {
|
|||
async function confirmKeygen(req, res) {
|
||||
logger.debug('Confirm keygen call')
|
||||
const { x, y, epoch } = req.body
|
||||
const message = buildMessage(Action.CONFIRM_KEYGEN, epoch, x, y)
|
||||
const message = buildMessage(Action.CONFIRM_KEYGEN, epoch, padZeros(x, 64), padZeros(y, 64))
|
||||
await processMessage(message)
|
||||
res.send()
|
||||
logger.debug('Confirm keygen end')
|
||||
|
@ -230,7 +230,7 @@ async function confirmCloseEpoch(req, res) {
|
|||
|
||||
async function voteStartVoting(req, res) {
|
||||
logger.info('Voting for starting new epoch voting process')
|
||||
const epoch = boundX(await bridge.epoch())
|
||||
const epoch = await bridge.epoch()
|
||||
const message = buildMessage(Action.VOTE_START_VOTING, epoch)
|
||||
await processMessage(message)
|
||||
res.send('Voted\n')
|
||||
|
@ -239,7 +239,7 @@ async function voteStartVoting(req, res) {
|
|||
|
||||
async function voteStartKeygen(req, res) {
|
||||
logger.info('Voting for starting new epoch keygen')
|
||||
const epoch = boundX(await bridge.epoch())
|
||||
const epoch = await bridge.epoch()
|
||||
const message = buildMessage(Action.VOTE_START_KEYGEN, epoch)
|
||||
await processMessage(message)
|
||||
res.send('Voted\n')
|
||||
|
@ -248,7 +248,7 @@ async function voteStartKeygen(req, res) {
|
|||
|
||||
async function voteCancelKeygen(req, res) {
|
||||
logger.info('Voting for cancelling new epoch keygen')
|
||||
const epoch = boundX(await bridge.nextEpoch())
|
||||
const epoch = await bridge.nextEpoch()
|
||||
const message = buildMessage(Action.VOTE_CANCEL_KEYGEN, epoch)
|
||||
await processMessage(message)
|
||||
res.send('Voted\n')
|
||||
|
@ -258,8 +258,8 @@ async function voteCancelKeygen(req, res) {
|
|||
async function voteAddValidator(req, res) {
|
||||
if (ethers.utils.isHexString(req.params.validator, 20)) {
|
||||
logger.info('Voting for adding new validator')
|
||||
const epoch = boundX(await bridge.epoch())
|
||||
const message = buildMessage(Action.VOTE_ADD_VALIDATOR, epoch, req.params.validator)
|
||||
const epoch = await bridge.epoch()
|
||||
const message = buildMessage(Action.VOTE_ADD_VALIDATOR, epoch, req.params.validator, padZeros('', 18))
|
||||
await processMessage(message)
|
||||
res.send('Voted\n')
|
||||
logger.info('Voted successfully')
|
||||
|
@ -269,12 +269,8 @@ async function voteAddValidator(req, res) {
|
|||
async function voteChangeThreshold(req, res) {
|
||||
if (/^[0-9]+$/.test(req.params.threshold)) {
|
||||
logger.info('Voting for changing threshold')
|
||||
const epoch = boundX(await bridge.epoch())
|
||||
const message = buildMessage(
|
||||
Action.VOTE_CHANGE_THRESHOLD,
|
||||
epoch,
|
||||
parseInt(req.params.threshold, 10)
|
||||
)
|
||||
const epoch = await bridge.epoch()
|
||||
const message = buildMessage(Action.VOTE_CHANGE_THRESHOLD, epoch, parseInt(req.params.threshold, 10), padZeros('', 54))
|
||||
await processMessage(message)
|
||||
res.send('Voted\n')
|
||||
logger.info('Voted successfully')
|
||||
|
@ -284,8 +280,8 @@ async function voteChangeThreshold(req, res) {
|
|||
async function voteChangeCloseEpoch(req, res) {
|
||||
if (req.params.closeEpoch === 'true' || req.params.closeEpoch === 'false') {
|
||||
logger.info('Voting for changing close epoch')
|
||||
const epoch = boundX(await bridge.epoch())
|
||||
const message = buildMessage(Action.VOTE_CHANGE_CLOSE_EPOCH, epoch, req.params.closeEpoch === 'true')
|
||||
const epoch = await bridge.epoch()
|
||||
const message = buildMessage(Action.VOTE_CHANGE_CLOSE_EPOCH, epoch, req.params.closeEpoch === 'true', padZeros('', 56))
|
||||
await processMessage(message)
|
||||
res.send('Voted\n')
|
||||
logger.info('Voted successfully')
|
||||
|
@ -295,8 +291,8 @@ async function voteChangeCloseEpoch(req, res) {
|
|||
async function voteRemoveValidator(req, res) {
|
||||
if (ethers.utils.isHexString(req.params.validator, 20)) {
|
||||
logger.info('Voting for removing validator')
|
||||
const epoch = boundX(await bridge.epoch())
|
||||
const message = buildMessage(Action.VOTE_REMOVE_VALIDATOR, epoch, req.params.validator)
|
||||
const epoch = await bridge.epoch()
|
||||
const message = buildMessage(Action.VOTE_REMOVE_VALIDATOR, epoch, req.params.validator, padZeros('', 18))
|
||||
await processMessage(message)
|
||||
res.send('Voted\n')
|
||||
logger.info('Voted successfully')
|
||||
|
@ -310,7 +306,7 @@ async function transfer(req, res) {
|
|||
} = req.body
|
||||
if (ethers.utils.isHexString(to, 20)) {
|
||||
logger.info(`Calling transfer to ${to}, 0x${value} tokens`)
|
||||
const message = buildMessage(Action.TRANSFER, epoch, hash, to, value)
|
||||
const message = buildMessage(Action.TRANSFER, epoch, hash, to, padZeros(value, 24))
|
||||
logger.info(`Message for sign: ${message.toString('hex')}`)
|
||||
await processMessage(message)
|
||||
}
|
||||
|
@ -339,19 +335,19 @@ async function info(req, res) {
|
|||
] = await Promise.all([
|
||||
bridge.getX().then((value) => new BN(value).toString(16)),
|
||||
bridge.getY().then((value) => new BN(value).toString(16)),
|
||||
bridge.epoch().then(boundX),
|
||||
bridge.getRangeSize().then(boundX),
|
||||
bridge.getNextRangeSize().then(boundX),
|
||||
bridge.epoch(),
|
||||
bridge.getRangeSize(),
|
||||
bridge.getNextRangeSize(),
|
||||
bridge.getCloseEpoch(),
|
||||
bridge.getNextCloseEpoch(),
|
||||
bridge.getStartBlock().then(boundX),
|
||||
bridge.getNonce().then(boundX),
|
||||
bridge.nextEpoch().then(boundX),
|
||||
bridge.getThreshold().then(boundX),
|
||||
bridge.getNextThreshold().then(boundX),
|
||||
bridge.getStartBlock(),
|
||||
bridge.getNonce(),
|
||||
bridge.nextEpoch(),
|
||||
bridge.getThreshold(),
|
||||
bridge.getNextThreshold(),
|
||||
bridge.getValidators(),
|
||||
bridge.getNextValidators(),
|
||||
bridge.status().then(boundX),
|
||||
bridge.status(),
|
||||
token.balanceOf(HOME_BRIDGE_ADDRESS)
|
||||
.then((value) => parseFloat(new BN(value).dividedBy(10 ** 18).toFixed(8, 3)))
|
||||
])
|
||||
|
|
|
@ -23,17 +23,8 @@ function decodeStatus(status) {
|
|||
}
|
||||
}
|
||||
|
||||
function boundX(x) {
|
||||
try {
|
||||
return x.toNumber()
|
||||
} catch (e) {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Ok,
|
||||
Err,
|
||||
decodeStatus,
|
||||
boundX
|
||||
decodeStatus
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ const tokenAbi = [
|
|||
'function approve(address to, uint256 value)'
|
||||
]
|
||||
const bridgeAbi = [
|
||||
'function exchange(uint value)'
|
||||
'function exchange(uint96 value)'
|
||||
]
|
||||
|
||||
const PRIVATE_KEY = process.env.PRIVATE_KEY || HOME_PRIVATE_KEY
|
||||
|
|
|
@ -9,7 +9,7 @@ const abiToken = [
|
|||
'function allowance(address owner, address spender) view returns (uint)'
|
||||
]
|
||||
const abiBridge = [
|
||||
'function exchange(uint value)'
|
||||
'function exchange(uint96 value)'
|
||||
]
|
||||
|
||||
const provider = new ethers.providers.JsonRpcProvider(HOME_RPC_URL)
|
||||
|
|
Loading…
Reference in New Issue