Merge branch '119-Epic-rewards-for-bridge-validators' into 122-create-feemanager-basic-contract-and-its-interface
# Conflicts: # contracts/upgradeable_contracts/BasicHomeBridge.sol # test/erc_to_native/home_bridge.test.js
This commit is contained in:
commit
6deecdafac
|
@ -75,7 +75,7 @@ contract ERC677BridgeToken is
|
|||
}
|
||||
|
||||
function isContract(address _addr)
|
||||
private
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
pragma solidity 0.4.24;
|
||||
|
||||
import "./ERC677BridgeToken.sol";
|
||||
|
||||
|
||||
contract ERC677BridgeTokenRewardable is ERC677BridgeToken {
|
||||
|
||||
address public blockRewardContract;
|
||||
address public validatorSetContract;
|
||||
|
||||
constructor(
|
||||
string _name,
|
||||
string _symbol,
|
||||
uint8 _decimals
|
||||
) public ERC677BridgeToken(_name, _symbol, _decimals) {}
|
||||
|
||||
function setBlockRewardContract(address _blockRewardContract) onlyOwner public {
|
||||
require(_blockRewardContract != address(0) && isContract(_blockRewardContract));
|
||||
blockRewardContract = _blockRewardContract;
|
||||
}
|
||||
|
||||
function setValidatorSetContract(address _validatorSetContract) onlyOwner public {
|
||||
require(_validatorSetContract != address(0) && isContract(_validatorSetContract));
|
||||
validatorSetContract = _validatorSetContract;
|
||||
}
|
||||
|
||||
modifier onlyBlockRewardContract() {
|
||||
require(msg.sender == blockRewardContract);
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlyValidatorSetContract() {
|
||||
require(msg.sender == validatorSetContract);
|
||||
_;
|
||||
}
|
||||
|
||||
function mintReward(address[] _receivers, uint256[] _rewards) external onlyBlockRewardContract {
|
||||
for (uint256 i = 0; i < _receivers.length; i++) {
|
||||
address to = _receivers[i];
|
||||
uint256 amount = _rewards[i];
|
||||
|
||||
// Mint `amount` for `to`
|
||||
totalSupply_ = totalSupply_.add(amount);
|
||||
balances[to] = balances[to].add(amount);
|
||||
emit Mint(to, amount);
|
||||
emit Transfer(address(0), to, amount);
|
||||
}
|
||||
}
|
||||
|
||||
function stake(address _staker, uint256 _amount) external onlyValidatorSetContract {
|
||||
// Transfer `_amount` from `_staker` to `validatorSetContract`
|
||||
require(_amount <= balances[_staker]);
|
||||
balances[_staker] = balances[_staker].sub(_amount);
|
||||
balances[validatorSetContract] = balances[validatorSetContract].add(_amount);
|
||||
emit Transfer(_staker, validatorSetContract, _amount);
|
||||
}
|
||||
|
||||
function withdraw(address _staker, uint256 _amount) external onlyValidatorSetContract {
|
||||
// Transfer `_amount` from `validatorSetContract` to `_staker`
|
||||
require(_amount <= balances[validatorSetContract]);
|
||||
balances[validatorSetContract] = balances[validatorSetContract].sub(_amount);
|
||||
balances[_staker] = balances[_staker].add(_amount);
|
||||
emit Transfer(validatorSetContract, _staker, _amount);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
pragma solidity 0.4.24;
|
||||
|
||||
|
||||
interface IOwnedUpgradeabilityProxy {
|
||||
function proxyOwner() public view returns (address);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
pragma solidity 0.4.24;
|
||||
|
||||
|
||||
contract ValidatorSet {
|
||||
constructor() {}
|
||||
}
|
|
@ -1,20 +1,23 @@
|
|||
pragma solidity 0.4.24;
|
||||
import "../IBridgeValidators.sol";
|
||||
import "./OwnedUpgradeability.sol";
|
||||
import "../upgradeability/EternalStorage.sol";
|
||||
import "../libraries/SafeMath.sol";
|
||||
import "./Validatable.sol";
|
||||
import "./Ownable.sol";
|
||||
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol";
|
||||
|
||||
|
||||
contract BasicBridge is EternalStorage, Validatable {
|
||||
contract BasicBridge is EternalStorage, Validatable, Ownable, OwnedUpgradeability {
|
||||
using SafeMath for uint256;
|
||||
|
||||
event GasPriceChanged(uint256 gasPrice);
|
||||
event RequiredBlockConfirmationChanged(uint256 requiredBlockConfirmations);
|
||||
event DailyLimitChanged(uint256 newLimit);
|
||||
event ExecutionDailyLimitChanged(uint256 newLimit);
|
||||
|
||||
function getBridgeInterfacesVersion() public pure returns(uint64 major, uint64 minor, uint64 patch) {
|
||||
return (2, 1, 0);
|
||||
return (2, 2, 0);
|
||||
}
|
||||
|
||||
function setGasPrice(uint256 _gasPrice) public onlyOwner {
|
||||
|
@ -49,6 +52,14 @@ contract BasicBridge is EternalStorage, Validatable {
|
|||
return uintStorage[keccak256(abi.encodePacked("totalSpentPerDay", _day))];
|
||||
}
|
||||
|
||||
function setTotalExecutedPerDay(uint256 _day, uint256 _value) internal {
|
||||
uintStorage[keccak256(abi.encodePacked("totalExecutedPerDay", _day))] = _value;
|
||||
}
|
||||
|
||||
function totalExecutedPerDay(uint256 _day) public view returns(uint256) {
|
||||
return uintStorage[keccak256(abi.encodePacked("totalExecutedPerDay", _day))];
|
||||
}
|
||||
|
||||
function minPerTx() public view returns(uint256) {
|
||||
return uintStorage[keccak256(abi.encodePacked("minPerTx"))];
|
||||
}
|
||||
|
@ -57,6 +68,10 @@ contract BasicBridge is EternalStorage, Validatable {
|
|||
return uintStorage[keccak256(abi.encodePacked("maxPerTx"))];
|
||||
}
|
||||
|
||||
function executionMaxPerTx() public view returns(uint256) {
|
||||
return uintStorage[keccak256(abi.encodePacked("executionMaxPerTx"))];
|
||||
}
|
||||
|
||||
function setInitialize(bool _status) internal {
|
||||
boolStorage[keccak256(abi.encodePacked("isInitialized"))] = _status;
|
||||
}
|
||||
|
@ -78,6 +93,20 @@ contract BasicBridge is EternalStorage, Validatable {
|
|||
return uintStorage[keccak256(abi.encodePacked("dailyLimit"))];
|
||||
}
|
||||
|
||||
function setExecutionDailyLimit(uint256 _dailyLimit) public onlyOwner {
|
||||
uintStorage[keccak256(abi.encodePacked("executionDailyLimit"))] = _dailyLimit;
|
||||
emit ExecutionDailyLimitChanged(_dailyLimit);
|
||||
}
|
||||
|
||||
function executionDailyLimit() public view returns(uint256) {
|
||||
return uintStorage[keccak256(abi.encodePacked("executionDailyLimit"))];
|
||||
}
|
||||
|
||||
function setExecutionMaxPerTx(uint256 _maxPerTx) external onlyOwner {
|
||||
require(_maxPerTx < executionDailyLimit());
|
||||
uintStorage[keccak256(abi.encodePacked("executionMaxPerTx"))] = _maxPerTx;
|
||||
}
|
||||
|
||||
function setMaxPerTx(uint256 _maxPerTx) external onlyOwner {
|
||||
require(_maxPerTx < dailyLimit());
|
||||
uintStorage[keccak256(abi.encodePacked("maxPerTx"))] = _maxPerTx;
|
||||
|
@ -93,7 +122,12 @@ contract BasicBridge is EternalStorage, Validatable {
|
|||
return dailyLimit() >= nextLimit && _amount <= maxPerTx() && _amount >= minPerTx();
|
||||
}
|
||||
|
||||
function claimTokens(address _token, address _to) public onlyOwner {
|
||||
function withinExecutionLimit(uint256 _amount) public view returns(bool) {
|
||||
uint256 nextLimit = totalExecutedPerDay(getCurrentDay()).add(_amount);
|
||||
return executionDailyLimit() >= nextLimit && _amount <= executionMaxPerTx();
|
||||
}
|
||||
|
||||
function claimTokens(address _token, address _to) public onlyIfOwnerOfProxy {
|
||||
require(_to != address(0));
|
||||
if (_token == address(0)) {
|
||||
_to.transfer(address(this).balance);
|
||||
|
|
|
@ -17,16 +17,18 @@ contract BasicForeignBridge is EternalStorage, Validatable {
|
|||
bytes32 txHash;
|
||||
address contractAddress;
|
||||
(recipient, amount, txHash, contractAddress) = Message.parseMessage(message);
|
||||
require(contractAddress == address(this));
|
||||
require(!relayedMessages(txHash));
|
||||
setRelayedMessages(txHash, true);
|
||||
require(onExecuteMessage(recipient, amount));
|
||||
emit RelayedMessage(recipient, amount, txHash);
|
||||
if (messageWithinLimits(amount)) {
|
||||
require(contractAddress == address(this));
|
||||
require(!relayedMessages(txHash));
|
||||
setRelayedMessages(txHash, true);
|
||||
require(onExecuteMessage(recipient, amount));
|
||||
emit RelayedMessage(recipient, amount, txHash);
|
||||
} else {
|
||||
onFailedMessage(recipient, amount, txHash);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -35,4 +37,8 @@ contract BasicForeignBridge is EternalStorage, Validatable {
|
|||
function relayedMessages(bytes32 _txHash) public view returns(bool) {
|
||||
return boolStorage[keccak256(abi.encodePacked("relayedMessages", _txHash))];
|
||||
}
|
||||
|
||||
function messageWithinLimits(uint256) internal view returns(bool);
|
||||
|
||||
function onFailedMessage(address, uint256, bytes32) internal;
|
||||
}
|
||||
|
|
|
@ -17,27 +17,31 @@ contract BasicHomeBridge is EternalStorage, Validatable {
|
|||
event CollectedSignatures(address authorityResponsibleForRelay, bytes32 messageHash, uint256 NumberOfCollectedSignatures);
|
||||
|
||||
function executeAffirmation(address recipient, uint256 value, bytes32 transactionHash) external onlyValidator {
|
||||
bytes32 hashMsg = keccak256(abi.encodePacked(recipient, value, transactionHash));
|
||||
bytes32 hashSender = keccak256(abi.encodePacked(msg.sender, hashMsg));
|
||||
// Duplicated affirmations
|
||||
require(!affirmationsSigned(hashSender));
|
||||
setAffirmationsSigned(hashSender, true);
|
||||
if (affirmationWithinLimits(value)) {
|
||||
bytes32 hashMsg = keccak256(abi.encodePacked(recipient, value, transactionHash));
|
||||
bytes32 hashSender = keccak256(abi.encodePacked(msg.sender, hashMsg));
|
||||
// Duplicated affirmations
|
||||
require(!affirmationsSigned(hashSender));
|
||||
setAffirmationsSigned(hashSender, true);
|
||||
|
||||
uint256 signed = numAffirmationsSigned(hashMsg);
|
||||
require(!isAlreadyProcessed(signed));
|
||||
// the check above assumes that the case when the value could be overflew will not happen in the addition operation below
|
||||
signed = signed + 1;
|
||||
uint256 signed = numAffirmationsSigned(hashMsg);
|
||||
require(!isAlreadyProcessed(signed));
|
||||
// the check above assumes that the case when the value could be overflew will not happen in the addition operation below
|
||||
signed = signed + 1;
|
||||
|
||||
setNumAffirmationsSigned(hashMsg, signed);
|
||||
setNumAffirmationsSigned(hashMsg, signed);
|
||||
|
||||
emit SignedForAffirmation(msg.sender, transactionHash);
|
||||
emit SignedForAffirmation(msg.sender, transactionHash);
|
||||
|
||||
if (signed >= requiredSignatures()) {
|
||||
// If the bridge contract does not own enough tokens to transfer
|
||||
// it will couse funds lock on the home side of the bridge
|
||||
setNumAffirmationsSigned(hashMsg, markAsProcessed(signed));
|
||||
require(onExecuteAffirmation(recipient, value));
|
||||
emit AffirmationCompleted(recipient, value, transactionHash);
|
||||
if (signed >= requiredSignatures()) {
|
||||
// If the bridge contract does not own enough tokens to transfer
|
||||
// it will couse funds lock on the home side of the bridge
|
||||
setNumAffirmationsSigned(hashMsg, markAsProcessed(signed));
|
||||
require(onExecuteAffirmation(recipient, value));
|
||||
emit AffirmationCompleted(recipient, value, transactionHash);
|
||||
}
|
||||
} else {
|
||||
onFailedAffirmation(recipient, value, transactionHash);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,6 +165,13 @@ contract BasicHomeBridge is EternalStorage, Validatable {
|
|||
return Message.requiredMessageLength();
|
||||
}
|
||||
|
||||
function affirmationWithinLimits(uint256) internal view returns(bool) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function onFailedAffirmation(address, uint256, bytes32) internal {
|
||||
}
|
||||
|
||||
function feeManagerContract() public view returns(address) {
|
||||
return addressStorage[keccak256(abi.encodePacked("feeManagerContract"))];
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
pragma solidity 0.4.24;
|
||||
|
||||
import "../upgradeability/EternalStorage.sol";
|
||||
import "../libraries/SafeMath.sol";
|
||||
import "./OwnedUpgradeability.sol";
|
||||
|
||||
|
||||
contract OverdrawManagement is EternalStorage, OwnedUpgradeability {
|
||||
using SafeMath for uint256;
|
||||
|
||||
event UserRequestForSignature(address recipient, uint256 value);
|
||||
|
||||
function fixAssetsAboveLimits(bytes32 txHash, bool unlockOnForeign) external onlyIfOwnerOfProxy {
|
||||
require(!fixedAssets(txHash));
|
||||
address recipient;
|
||||
uint256 value;
|
||||
(recipient, value) = txAboveLimits(txHash);
|
||||
require(recipient != address(0) && value > 0);
|
||||
setOutOfLimitAmount(outOfLimitAmount().sub(value));
|
||||
if (unlockOnForeign) {
|
||||
emit UserRequestForSignature(recipient, value);
|
||||
}
|
||||
setFixedAssets(txHash, true);
|
||||
}
|
||||
|
||||
function outOfLimitAmount() public view returns(uint256) {
|
||||
return uintStorage[keccak256(abi.encodePacked("outOfLimitAmount"))];
|
||||
}
|
||||
|
||||
function fixedAssets(bytes32 _txHash) public view returns(bool) {
|
||||
return boolStorage[keccak256(abi.encodePacked("fixedAssets", _txHash))];
|
||||
}
|
||||
|
||||
function setOutOfLimitAmount(uint256 _value) internal {
|
||||
uintStorage[keccak256(abi.encodePacked("outOfLimitAmount"))] = _value;
|
||||
}
|
||||
|
||||
function txAboveLimits(bytes32 _txHash) internal view returns(address recipient, uint256 value) {
|
||||
recipient = addressStorage[keccak256(abi.encodePacked("txOutOfLimitRecipient", _txHash))];
|
||||
value = uintStorage[keccak256(abi.encodePacked("txOutOfLimitValue", _txHash))];
|
||||
}
|
||||
|
||||
function setTxAboveLimits(address _recipient, uint256 _value, bytes32 _txHash) internal {
|
||||
addressStorage[keccak256(abi.encodePacked("txOutOfLimitRecipient", _txHash))] = _recipient;
|
||||
uintStorage[keccak256(abi.encodePacked("txOutOfLimitValue", _txHash))] = _value;
|
||||
}
|
||||
|
||||
function setFixedAssets(bytes32 _txHash, bool _status) internal {
|
||||
boolStorage[keccak256(abi.encodePacked("fixedAssets", _txHash))] = _status;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
pragma solidity 0.4.24;
|
||||
|
||||
import "../IOwnedUpgradeabilityProxy.sol";
|
||||
|
||||
|
||||
contract OwnedUpgradeability {
|
||||
|
||||
function upgradeabilityAdmin() public view returns (address) {
|
||||
return IOwnedUpgradeabilityProxy(this).proxyOwner();
|
||||
}
|
||||
|
||||
// Avoid using onlyProxyOwner name to prevent issues with implementation from proxy contract
|
||||
modifier onlyIfOwnerOfProxy() {
|
||||
require(msg.sender == upgradeabilityAdmin());
|
||||
_;
|
||||
}
|
||||
}
|
|
@ -13,11 +13,6 @@ contract Validatable is EternalStorage {
|
|||
_;
|
||||
}
|
||||
|
||||
modifier onlyOwner() {
|
||||
require(validatorContract().owner() == msg.sender);
|
||||
_;
|
||||
}
|
||||
|
||||
function requiredSignatures() public view returns(uint256) {
|
||||
return validatorContract().requiredSignatures();
|
||||
}
|
||||
|
|
|
@ -16,17 +16,27 @@ contract ForeignBridgeErcToErc is BasicBridge, BasicForeignBridge {
|
|||
address _validatorContract,
|
||||
address _erc20token,
|
||||
uint256 _requiredBlockConfirmations,
|
||||
uint256 _gasPrice
|
||||
uint256 _gasPrice,
|
||||
uint256 _maxPerTx,
|
||||
uint256 _homeDailyLimit,
|
||||
uint256 _homeMaxPerTx,
|
||||
address _owner
|
||||
) public returns(bool) {
|
||||
require(!isInitialized());
|
||||
require(_validatorContract != address(0) && isContract(_validatorContract));
|
||||
require(_requiredBlockConfirmations != 0);
|
||||
require(_gasPrice > 0);
|
||||
require(_homeMaxPerTx < _homeDailyLimit);
|
||||
require(_owner != address(0));
|
||||
addressStorage[keccak256(abi.encodePacked("validatorContract"))] = _validatorContract;
|
||||
setErc20token(_erc20token);
|
||||
uintStorage[keccak256(abi.encodePacked("deployedAtBlock"))] = block.number;
|
||||
uintStorage[keccak256(abi.encodePacked("requiredBlockConfirmations"))] = _requiredBlockConfirmations;
|
||||
uintStorage[keccak256(abi.encodePacked("gasPrice"))] = _gasPrice;
|
||||
uintStorage[keccak256(abi.encodePacked("maxPerTx"))] = _maxPerTx;
|
||||
uintStorage[keccak256(abi.encodePacked("executionDailyLimit"))] = _homeDailyLimit;
|
||||
uintStorage[keccak256(abi.encodePacked("executionMaxPerTx"))] = _homeMaxPerTx;
|
||||
setOwner(_owner);
|
||||
setInitialize(true);
|
||||
return isInitialized();
|
||||
}
|
||||
|
@ -35,7 +45,7 @@ contract ForeignBridgeErcToErc is BasicBridge, BasicForeignBridge {
|
|||
return bytes4(keccak256(abi.encodePacked("erc-to-erc-core")));
|
||||
}
|
||||
|
||||
function claimTokens(address _token, address _to) public onlyOwner {
|
||||
function claimTokens(address _token, address _to) public onlyIfOwnerOfProxy {
|
||||
require(_token != address(erc20token()));
|
||||
super.claimTokens(_token, _to);
|
||||
}
|
||||
|
@ -45,6 +55,7 @@ contract ForeignBridgeErcToErc is BasicBridge, BasicForeignBridge {
|
|||
}
|
||||
|
||||
function onExecuteMessage(address _recipient, uint256 _amount) internal returns(bool){
|
||||
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount));
|
||||
return erc20token().transfer(_recipient, _amount);
|
||||
}
|
||||
|
||||
|
@ -52,4 +63,12 @@ contract ForeignBridgeErcToErc is BasicBridge, BasicForeignBridge {
|
|||
require(_token != address(0) && isContract(_token));
|
||||
addressStorage[keccak256(abi.encodePacked("erc20token"))] = _token;
|
||||
}
|
||||
|
||||
function messageWithinLimits(uint256 _amount) internal view returns(bool) {
|
||||
return withinExecutionLimit(_amount);
|
||||
}
|
||||
|
||||
function onFailedMessage(address, uint256, bytes32) internal {
|
||||
revert();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,12 @@ import "../../IBurnableMintableERC677Token.sol";
|
|||
import "../../ERC677Receiver.sol";
|
||||
import "../BasicHomeBridge.sol";
|
||||
import "../ERC677Bridge.sol";
|
||||
import "../OverdrawManagement.sol";
|
||||
|
||||
|
||||
contract HomeBridgeErcToErc is ERC677Receiver, EternalStorage, BasicBridge, BasicHomeBridge, ERC677Bridge {
|
||||
contract HomeBridgeErcToErc is ERC677Receiver, EternalStorage, BasicBridge, BasicHomeBridge, ERC677Bridge, OverdrawManagement {
|
||||
|
||||
event AmountLimitExceeded(address recipient, uint256 value, bytes32 transactionHash);
|
||||
|
||||
function initialize (
|
||||
address _validatorContract,
|
||||
|
@ -18,8 +21,10 @@ contract HomeBridgeErcToErc is ERC677Receiver, EternalStorage, BasicBridge, Basi
|
|||
uint256 _minPerTx,
|
||||
uint256 _homeGasPrice,
|
||||
uint256 _requiredBlockConfirmations,
|
||||
address _erc677token
|
||||
|
||||
address _erc677token,
|
||||
uint256 _foreignDailyLimit,
|
||||
uint256 _foreignMaxPerTx,
|
||||
address _owner
|
||||
) public
|
||||
returns(bool)
|
||||
{
|
||||
|
@ -28,6 +33,8 @@ contract HomeBridgeErcToErc is ERC677Receiver, EternalStorage, BasicBridge, Basi
|
|||
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;
|
||||
uintStorage[keccak256(abi.encodePacked("dailyLimit"))] = _dailyLimit;
|
||||
|
@ -35,6 +42,9 @@ contract HomeBridgeErcToErc is ERC677Receiver, EternalStorage, BasicBridge, Basi
|
|||
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);
|
||||
setErc677token(_erc677token);
|
||||
|
||||
|
@ -45,11 +55,12 @@ contract HomeBridgeErcToErc is ERC677Receiver, EternalStorage, BasicBridge, Basi
|
|||
return bytes4(keccak256(abi.encodePacked("erc-to-erc-core")));
|
||||
}
|
||||
|
||||
function () public {
|
||||
function () payable public {
|
||||
revert();
|
||||
}
|
||||
|
||||
function onExecuteAffirmation(address _recipient, uint256 _value) internal returns(bool) {
|
||||
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_value));
|
||||
return erc677token().mint(_recipient, _value);
|
||||
}
|
||||
|
||||
|
@ -57,4 +68,17 @@ contract HomeBridgeErcToErc is ERC677Receiver, EternalStorage, BasicBridge, Basi
|
|||
emit UserRequestForSignature(_from, _value);
|
||||
}
|
||||
|
||||
function affirmationWithinLimits(uint256 _amount) internal view returns(bool) {
|
||||
return withinExecutionLimit(_amount);
|
||||
}
|
||||
|
||||
function onFailedAffirmation(address _recipient, uint256 _value, bytes32 _txHash) internal {
|
||||
address recipient;
|
||||
uint256 value;
|
||||
(recipient, value) = txAboveLimits(_txHash);
|
||||
require(recipient == address(0) && value == 0);
|
||||
setOutOfLimitAmount(outOfLimitAmount().add(_value));
|
||||
setTxAboveLimits(_recipient, _value, _txHash);
|
||||
emit AmountLimitExceeded(_recipient, _value, _txHash);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,17 +15,27 @@ contract ForeignBridgeErcToNative is BasicBridge, BasicForeignBridge {
|
|||
address _validatorContract,
|
||||
address _erc20token,
|
||||
uint256 _requiredBlockConfirmations,
|
||||
uint256 _gasPrice
|
||||
uint256 _gasPrice,
|
||||
uint256 _maxPerTx,
|
||||
uint256 _homeDailyLimit,
|
||||
uint256 _homeMaxPerTx,
|
||||
address _owner
|
||||
) public returns(bool) {
|
||||
require(!isInitialized());
|
||||
require(_validatorContract != address(0) && isContract(_validatorContract));
|
||||
require(_requiredBlockConfirmations != 0);
|
||||
require(_gasPrice > 0);
|
||||
require(_homeMaxPerTx < _homeDailyLimit);
|
||||
require(_owner != address(0));
|
||||
addressStorage[keccak256(abi.encodePacked("validatorContract"))] = _validatorContract;
|
||||
setErc20token(_erc20token);
|
||||
uintStorage[keccak256(abi.encodePacked("deployedAtBlock"))] = block.number;
|
||||
uintStorage[keccak256(abi.encodePacked("requiredBlockConfirmations"))] = _requiredBlockConfirmations;
|
||||
uintStorage[keccak256(abi.encodePacked("gasPrice"))] = _gasPrice;
|
||||
uintStorage[keccak256(abi.encodePacked("maxPerTx"))] = _maxPerTx;
|
||||
uintStorage[keccak256(abi.encodePacked("executionDailyLimit"))] = _homeDailyLimit;
|
||||
uintStorage[keccak256(abi.encodePacked("executionMaxPerTx"))] = _homeMaxPerTx;
|
||||
setOwner(_owner);
|
||||
setInitialize(true);
|
||||
return isInitialized();
|
||||
}
|
||||
|
@ -34,7 +44,7 @@ contract ForeignBridgeErcToNative is BasicBridge, BasicForeignBridge {
|
|||
return bytes4(keccak256(abi.encodePacked("erc-to-native-core")));
|
||||
}
|
||||
|
||||
function claimTokens(address _token, address _to) public onlyOwner {
|
||||
function claimTokens(address _token, address _to) public onlyIfOwnerOfProxy {
|
||||
require(_token != address(erc20token()));
|
||||
super.claimTokens(_token, _to);
|
||||
}
|
||||
|
@ -44,6 +54,7 @@ contract ForeignBridgeErcToNative is BasicBridge, BasicForeignBridge {
|
|||
}
|
||||
|
||||
function onExecuteMessage(address _recipient, uint256 _amount) internal returns(bool) {
|
||||
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount));
|
||||
return erc20token().transfer(_recipient, _amount);
|
||||
}
|
||||
|
||||
|
@ -51,4 +62,12 @@ contract ForeignBridgeErcToNative is BasicBridge, BasicForeignBridge {
|
|||
require(_token != address(0) && isContract(_token));
|
||||
addressStorage[keccak256(abi.encodePacked("erc20token"))] = _token;
|
||||
}
|
||||
|
||||
function messageWithinLimits(uint256 _amount) internal view returns(bool) {
|
||||
return withinExecutionLimit(_amount);
|
||||
}
|
||||
|
||||
function onFailedMessage(address, uint256, bytes32) internal {
|
||||
revert();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,12 @@ import "../../IBlockReward.sol";
|
|||
import "../../ERC677Receiver.sol";
|
||||
import "../BasicHomeBridge.sol";
|
||||
import "../ERC677Bridge.sol";
|
||||
import "../OverdrawManagement.sol";
|
||||
|
||||
|
||||
contract HomeBridgeErcToNative is EternalStorage, BasicBridge, BasicHomeBridge {
|
||||
contract HomeBridgeErcToNative is EternalStorage, BasicBridge, BasicHomeBridge, OverdrawManagement {
|
||||
|
||||
event AmountLimitExceeded(address recipient, uint256 value, bytes32 transactionHash);
|
||||
|
||||
function () public payable {
|
||||
require(msg.value > 0);
|
||||
|
@ -37,8 +40,10 @@ contract HomeBridgeErcToNative is EternalStorage, BasicBridge, BasicHomeBridge {
|
|||
uint256 _minPerTx,
|
||||
uint256 _homeGasPrice,
|
||||
uint256 _requiredBlockConfirmations,
|
||||
address _blockReward
|
||||
|
||||
address _blockReward,
|
||||
uint256 _foreignDailyLimit,
|
||||
uint256 _foreignMaxPerTx,
|
||||
address _owner
|
||||
) public returns(bool)
|
||||
{
|
||||
require(!isInitialized());
|
||||
|
@ -46,6 +51,8 @@ contract HomeBridgeErcToNative is EternalStorage, BasicBridge, BasicHomeBridge {
|
|||
require(_requiredBlockConfirmations > 0);
|
||||
require(_minPerTx > 0 && _maxPerTx > _minPerTx && _dailyLimit > _maxPerTx);
|
||||
require(_blockReward == address(0) || isContract(_blockReward));
|
||||
require(_foreignMaxPerTx < _foreignDailyLimit);
|
||||
require(_owner != address(0));
|
||||
addressStorage[keccak256(abi.encodePacked("validatorContract"))] = _validatorContract;
|
||||
uintStorage[keccak256(abi.encodePacked("deployedAtBlock"))] = block.number;
|
||||
uintStorage[keccak256(abi.encodePacked("dailyLimit"))] = _dailyLimit;
|
||||
|
@ -54,6 +61,9 @@ contract HomeBridgeErcToNative is EternalStorage, BasicBridge, BasicHomeBridge {
|
|||
uintStorage[keccak256(abi.encodePacked("gasPrice"))] = _homeGasPrice;
|
||||
uintStorage[keccak256(abi.encodePacked("requiredBlockConfirmations"))] = _requiredBlockConfirmations;
|
||||
addressStorage[keccak256(abi.encodePacked("blockRewardContract"))] = _blockReward;
|
||||
uintStorage[keccak256(abi.encodePacked("executionDailyLimit"))] = _foreignDailyLimit;
|
||||
uintStorage[keccak256(abi.encodePacked("executionMaxPerTx"))] = _foreignMaxPerTx;
|
||||
setOwner(_owner);
|
||||
setInitialize(true);
|
||||
|
||||
return isInitialized();
|
||||
|
@ -77,6 +87,7 @@ contract HomeBridgeErcToNative is EternalStorage, BasicBridge, BasicHomeBridge {
|
|||
}
|
||||
|
||||
function onExecuteAffirmation(address _recipient, uint256 _value) internal returns(bool) {
|
||||
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_value));
|
||||
IBlockReward blockReward = blockRewardContract();
|
||||
require(blockReward != address(0));
|
||||
uint256 valueToMint = _value;
|
||||
|
@ -98,4 +109,18 @@ contract HomeBridgeErcToNative is EternalStorage, BasicBridge, BasicHomeBridge {
|
|||
function setTotalBurntCoins(uint256 _amount) internal {
|
||||
uintStorage[keccak256(abi.encodePacked("totalBurntCoins"))] = _amount;
|
||||
}
|
||||
|
||||
function affirmationWithinLimits(uint256 _amount) internal view returns(bool) {
|
||||
return withinExecutionLimit(_amount);
|
||||
}
|
||||
|
||||
function onFailedAffirmation(address _recipient, uint256 _value, bytes32 _txHash) internal {
|
||||
address recipient;
|
||||
uint256 value;
|
||||
(recipient, value) = txAboveLimits(_txHash);
|
||||
require(recipient == address(0) && value == 0);
|
||||
setOutOfLimitAmount(outOfLimitAmount().add(_value));
|
||||
setTxAboveLimits(_recipient, _value, _txHash);
|
||||
emit AmountLimitExceeded(_recipient, _value, _txHash);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,17 @@ contract ForeignBridgeNativeToErc is ERC677Receiver, BasicBridge, BasicForeignBr
|
|||
uint256 _maxPerTx,
|
||||
uint256 _minPerTx,
|
||||
uint256 _foreignGasPrice,
|
||||
uint256 _requiredBlockConfirmations
|
||||
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);
|
||||
uintStorage[keccak256(abi.encodePacked("dailyLimit"))] = _dailyLimit;
|
||||
|
@ -34,6 +39,9 @@ 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();
|
||||
}
|
||||
|
@ -42,11 +50,12 @@ contract ForeignBridgeNativeToErc is ERC677Receiver, BasicBridge, BasicForeignBr
|
|||
return bytes4(keccak256(abi.encodePacked("native-to-erc-core")));
|
||||
}
|
||||
|
||||
function claimTokensFromErc677(address _token, address _to) external onlyOwner {
|
||||
function claimTokensFromErc677(address _token, address _to) external onlyIfOwnerOfProxy {
|
||||
erc677token().claimTokens(_token, _to);
|
||||
}
|
||||
|
||||
function onExecuteMessage(address _recipient, uint256 _amount) internal returns(bool){
|
||||
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount));
|
||||
return erc677token().mint(_recipient, _amount);
|
||||
}
|
||||
|
||||
|
@ -54,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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,10 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicBridge, BasicHomeBridge {
|
|||
uint256 _maxPerTx,
|
||||
uint256 _minPerTx,
|
||||
uint256 _homeGasPrice,
|
||||
uint256 _requiredBlockConfirmations
|
||||
uint256 _requiredBlockConfirmations,
|
||||
uint256 _foreignDailyLimit,
|
||||
uint256 _foreignMaxPerTx,
|
||||
address _owner
|
||||
) public
|
||||
returns(bool)
|
||||
{
|
||||
|
@ -28,6 +31,8 @@ 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;
|
||||
uintStorage[keccak256(abi.encodePacked("dailyLimit"))] = _dailyLimit;
|
||||
|
@ -35,6 +40,9 @@ 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();
|
||||
}
|
||||
|
@ -52,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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#BRIDGE_MODE=ERC_TO_ERC
|
||||
BRIDGE_MODE=NATIVE_TO_ERC
|
||||
DEPLOYMENT_ACCOUNT_PRIVATE_KEY=67..14
|
||||
DEPLOYMENT_GAS_LIMIT=4000000
|
||||
DEPLOYMENT_GAS_LIMIT=5000000
|
||||
HOME_DEPLOYMENT_GAS_PRICE=10000000000
|
||||
FOREIGN_DEPLOYMENT_GAS_PRICE=10000000000
|
||||
GET_RECEIPT_INTERVAL_IN_MILLISECONDS=3000
|
||||
|
@ -11,22 +11,22 @@ BRIDGEABLE_TOKEN_SYMBOL=TEST
|
|||
BRIDGEABLE_TOKEN_DECIMALS=18
|
||||
|
||||
HOME_RPC_URL=https://sokol.poa.network
|
||||
HOME_OWNER_MULTISIG=0x
|
||||
HOME_UPGRADEABLE_ADMIN_VALIDATORS=0x
|
||||
HOME_UPGRADEABLE_ADMIN_BRIDGE=0x
|
||||
HOME_BRIDGE_OWNER=0x
|
||||
HOME_VALIDATORS_OWNER=0x
|
||||
HOME_UPGRADEABLE_ADMIN=0x
|
||||
HOME_DAILY_LIMIT=30000000000000000000000000
|
||||
HOME_MAX_AMOUNT_PER_TX=1500000000000000000000000
|
||||
HOME_MIN_AMOUNT_PER_TX=500000000000000000
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS=1
|
||||
HOME_GAS_PRICE=1000000000
|
||||
|
||||
#for bridge erc to native mode
|
||||
#for bridge erc_to_native and native_to_erc mode
|
||||
BLOCK_REWARD_ADDRESS=
|
||||
|
||||
FOREIGN_RPC_URL=https://sokol.poa.network
|
||||
FOREIGN_OWNER_MULTISIG=0x
|
||||
FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS=0x
|
||||
FOREIGN_UPGRADEABLE_ADMIN_BRIDGE=0x
|
||||
FOREIGN_BRIDGE_OWNER=0x
|
||||
FOREIGN_VALIDATORS_OWNER=0x
|
||||
FOREIGN_UPGRADEABLE_ADMIN=0x
|
||||
FOREIGN_DAILY_LIMIT=15000000000000000000000000
|
||||
FOREIGN_MAX_AMOUNT_PER_TX=750000000000000000000000
|
||||
FOREIGN_MIN_AMOUNT_PER_TX=500000000000000000
|
||||
|
@ -39,3 +39,7 @@ REQUIRED_NUMBER_OF_VALIDATORS=1
|
|||
#If several validators are used, list them separated by space without quotes
|
||||
#E.g. VALIDATORS=0x 0x 0x
|
||||
VALIDATORS=0x
|
||||
|
||||
#for bridge native_to_erc mode
|
||||
DEPLOY_REWARDABLE_TOKEN=false
|
||||
DPOS_VALIDATOR_SET_ADDRESS=
|
||||
|
|
100
deploy/README.md
100
deploy/README.md
|
@ -59,14 +59,13 @@ BRIDGEABLE_TOKEN_DECIMALS=18
|
|||
# The RPC channel to a Home node able to handle deployment/configuration
|
||||
# transactions.
|
||||
HOME_RPC_URL=https://poa.infura.io
|
||||
# The address of an administrator on the Home network who can change bridge
|
||||
# parameters and a validator's contract. For extra security we recommended using
|
||||
# a multi-sig wallet contract address here.
|
||||
HOME_OWNER_MULTISIG=0x
|
||||
# The address from which a validator's contract can be upgraded on Home.
|
||||
HOME_UPGRADEABLE_ADMIN_VALIDATORS=0x
|
||||
# The address from which the bridge's contract can be upgraded on Home.
|
||||
HOME_UPGRADEABLE_ADMIN_BRIDGE=0x
|
||||
# Address on Home network with permissions to change parameters of the bridge contract.
|
||||
# For extra security we recommended using a multi-sig wallet contract address here.
|
||||
HOME_BRIDGE_OWNER=0x
|
||||
# Address on Home network with permissions to change parameters of bridge validator contract.
|
||||
HOME_VALIDATORS_OWNER=0x
|
||||
# Address on Home network with permissions to upgrade the bridge contract and the bridge validator contract.
|
||||
HOME_UPGRADEABLE_ADMIN=0x
|
||||
# The daily transaction limit in Wei. As soon as this limit is exceeded, any
|
||||
# transaction which requests to relay assets will fail.
|
||||
HOME_DAILY_LIMIT=30000000000000000000000000
|
||||
|
@ -89,14 +88,13 @@ HOME_GAS_PRICE=1000000000
|
|||
# The RPC channel to a Foreign node able to handle deployment/configuration
|
||||
# transactions.
|
||||
FOREIGN_RPC_URL=https://mainnet.infura.io
|
||||
# The address of an administrator on the Foreign network who can change bridge
|
||||
# parameters and the validator's contract. For extra security we recommended
|
||||
# using a multi-sig wallet contract address here.
|
||||
FOREIGN_OWNER_MULTISIG=0x
|
||||
# The address from which a validator's contract can be upgraded on Foreign.
|
||||
FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS=0x
|
||||
# The address from which the bridge's contract can be upgraded on Foreign.
|
||||
FOREIGN_UPGRADEABLE_ADMIN_BRIDGE=0x
|
||||
# Address on Foreign network with permissions to change parameters of the bridge contract.
|
||||
# For extra security we recommended using a multi-sig wallet contract address here.
|
||||
FOREIGN_BRIDGE_OWNER=0x
|
||||
# Address on Foreign network with permissions to change parameters of bridge validator contract.
|
||||
FOREIGN_VALIDATORS_OWNER=0x
|
||||
# Address on Foreign network with permissions to upgrade the bridge contract and the bridge validator contract.
|
||||
FOREIGN_UPGRADEABLE_ADMIN=0x
|
||||
# The daily limit in Wei. As soon as this limit is exceeded, any transaction
|
||||
# requesting to relay assets will fail.
|
||||
FOREIGN_DAILY_LIMIT=15000000000000000000000000
|
||||
|
@ -125,6 +123,16 @@ REQUIRED_NUMBER_OF_VALIDATORS=1
|
|||
# the Foreign network to confirm that the finalized agreement was transferred
|
||||
# correctly to the Foreign network.
|
||||
VALIDATORS=0x 0x 0x
|
||||
|
||||
# The flag defining whether to use ERC677BridgeTokenRewardable contract instead of
|
||||
# ERC677BridgeToken.
|
||||
DEPLOY_REWARDABLE_TOKEN=false
|
||||
# The address of ValidatorSet contract used by ERC677BridgeTokenRewardable contract.
|
||||
# Makes sense only when DEPLOY_REWARDABLE_TOKEN=true
|
||||
DPOS_VALIDATOR_SET_ADDRESS=0x
|
||||
# The address of BlockReward contract used by ERC677BridgeTokenRewardable contract.
|
||||
# Makes sense only when DEPLOY_REWARDABLE_TOKEN=true
|
||||
BLOCK_REWARD_ADDRESS=0x
|
||||
```
|
||||
|
||||
|
||||
|
@ -163,14 +171,13 @@ BRIDGEABLE_TOKEN_DECIMALS=18
|
|||
# The RPC channel to a Home node able to handle deployment/configuration
|
||||
# transactions.
|
||||
HOME_RPC_URL=https://poa.infura.io
|
||||
# The address of an administrator on the Home network who can change bridge
|
||||
# parameters and a validator's contract. For extra security we recommended using
|
||||
# a multi-sig wallet contract address here.
|
||||
HOME_OWNER_MULTISIG=0x
|
||||
# The address from which a validator's contract can be upgraded on Home.
|
||||
HOME_UPGRADEABLE_ADMIN_VALIDATORS=0x
|
||||
# The address from which the bridge's contract can be upgraded on Home.
|
||||
HOME_UPGRADEABLE_ADMIN_BRIDGE=0x
|
||||
# Address on Home network with permissions to change parameters of the bridge contract.
|
||||
# For extra security we recommended using a multi-sig wallet contract address here.
|
||||
HOME_BRIDGE_OWNER=0x
|
||||
# Address on Home network with permissions to change parameters of bridge validator contract.
|
||||
HOME_VALIDATORS_OWNER=0x
|
||||
# Address on Home network with permissions to upgrade the bridge contract and the bridge validator contract.
|
||||
HOME_UPGRADEABLE_ADMIN=0x
|
||||
# The daily transaction limit in Wei. As soon as this limit is exceeded, any
|
||||
# transaction which requests to relay assets will fail.
|
||||
HOME_DAILY_LIMIT=30000000000000000000000000
|
||||
|
@ -193,14 +200,13 @@ HOME_GAS_PRICE=1000000000
|
|||
# The RPC channel to a Foreign node able to handle deployment/configuration
|
||||
# transactions.
|
||||
FOREIGN_RPC_URL=https://mainnet.infura.io
|
||||
# The address of an administrator on the Foreign network who can change bridge
|
||||
# parameters and the validator's contract. For extra security we recommended
|
||||
# using a multi-sig wallet contract address here.
|
||||
FOREIGN_OWNER_MULTISIG=0x
|
||||
# The address from which a validator's contract can be upgraded on Foreign.
|
||||
FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS=0x
|
||||
# The address from which the bridge's contract can be upgraded on Foreign.
|
||||
FOREIGN_UPGRADEABLE_ADMIN_BRIDGE=0x
|
||||
# Address on Foreign network with permissions to change parameters of the bridge contract.
|
||||
# For extra security we recommended using a multi-sig wallet contract address here.
|
||||
FOREIGN_BRIDGE_OWNER=0x
|
||||
# Address on Foreign network with permissions to change parameters of bridge validator contract.
|
||||
FOREIGN_VALIDATORS_OWNER=0x
|
||||
# Address on Foreign network with permissions to upgrade the bridge contract and the bridge validator contract.
|
||||
FOREIGN_UPGRADEABLE_ADMIN=0x
|
||||
# These three parameters are not used in this mode, but the deployment script
|
||||
# requires it to be set to some value.
|
||||
FOREIGN_DAILY_LIMIT=0
|
||||
|
@ -256,14 +262,13 @@ GET_RECEIPT_INTERVAL_IN_MILLISECONDS=3000
|
|||
# The RPC channel to a Home node able to handle deployment/configuration
|
||||
# transactions.
|
||||
HOME_RPC_URL=https://poa.infura.io
|
||||
# The address of an administrator on the Home network who can change bridge
|
||||
# parameters and a validator's contract. For extra security we recommended using
|
||||
# a multi-sig wallet contract address here.
|
||||
HOME_OWNER_MULTISIG=0x
|
||||
# The address from which a validator's contract can be upgraded on Home.
|
||||
HOME_UPGRADEABLE_ADMIN_VALIDATORS=0x
|
||||
# The address from which the bridge's contract can be upgraded on Home.
|
||||
HOME_UPGRADEABLE_ADMIN_BRIDGE=0x
|
||||
# Address on Home network with permissions to change parameters of the bridge contract.
|
||||
# For extra security we recommended using a multi-sig wallet contract address here.
|
||||
HOME_BRIDGE_OWNER=0x
|
||||
# Address on Home network with permissions to change parameters of bridge validator contract.
|
||||
HOME_VALIDATORS_OWNER=0x
|
||||
# Address on Home network with permissions to upgrade the bridge contract and the bridge validator contract.
|
||||
HOME_UPGRADEABLE_ADMIN=0x
|
||||
# The daily transaction limit in Wei. As soon as this limit is exceeded, any
|
||||
# transaction which requests to relay assets will fail.
|
||||
HOME_DAILY_LIMIT=30000000000000000000000000
|
||||
|
@ -289,14 +294,13 @@ BLOCK_REWARD_ADDRESS=0x
|
|||
# The RPC channel to a Foreign node able to handle deployment/configuration
|
||||
# transactions.
|
||||
FOREIGN_RPC_URL=https://mainnet.infura.io
|
||||
# The address of an administrator on the Foreign network who can change bridge
|
||||
# parameters and the validator's contract. For extra security we recommended
|
||||
# using a multi-sig wallet contract address here.
|
||||
FOREIGN_OWNER_MULTISIG=0x
|
||||
# The address from which a validator's contract can be upgraded on Foreign.
|
||||
FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS=0x
|
||||
# The address from which the bridge's contract can be upgraded on Foreign.
|
||||
FOREIGN_UPGRADEABLE_ADMIN_BRIDGE=0x
|
||||
# Address on Foreign network with permissions to change parameters of the bridge contract.
|
||||
# For extra security we recommended using a multi-sig wallet contract address here.
|
||||
FOREIGN_BRIDGE_OWNER=0x
|
||||
# Address on Foreign network with permissions to change parameters of bridge validator contract.
|
||||
FOREIGN_VALIDATORS_OWNER=0x
|
||||
# Address on Foreign network with permissions to upgrade the bridge contract and the bridge validator contract.
|
||||
FOREIGN_UPGRADEABLE_ADMIN=0x
|
||||
# These three parameters are not used in this mode, but the deployment script
|
||||
# requires it to be set to some value.
|
||||
FOREIGN_DAILY_LIMIT=0
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const env = require('./src/loadEnv')
|
||||
const { ZERO_ADDRESS } = require('./src/constants')
|
||||
|
||||
const { BRIDGE_MODE, BLOCK_REWARD_ADDRESS, ERC20_TOKEN_ADDRESS } = env
|
||||
const { BRIDGE_MODE, ERC20_TOKEN_ADDRESS } = env
|
||||
|
||||
const deployResultsPath = path.join(__dirname, './bridgeDeploymentResults.json')
|
||||
|
||||
|
@ -33,7 +32,7 @@ async function deployNativeToErc() {
|
|||
foreignBridge: {
|
||||
...foreignBridge,
|
||||
erc677
|
||||
},
|
||||
}
|
||||
},
|
||||
null,
|
||||
4
|
||||
|
@ -49,7 +48,9 @@ async function deployErcToErc() {
|
|||
const { homeBridge, erc677 } = await deployHome()
|
||||
const { foreignBridge } = await deployForeign()
|
||||
console.log('\nDeployment has been completed.\n\n')
|
||||
console.log(`[ Home ] HomeBridge: ${homeBridge.address} at block ${homeBridge.deployedBlockNumber}`)
|
||||
console.log(
|
||||
`[ Home ] HomeBridge: ${homeBridge.address} at block ${homeBridge.deployedBlockNumber}`
|
||||
)
|
||||
console.log(`[ Home ] ERC677 Bridgeable Token: ${erc677.address}`)
|
||||
console.log(
|
||||
`[ Foreign ] ForeignBridge: ${foreignBridge.address} at block ${
|
||||
|
@ -84,9 +85,7 @@ async function deployErcToNative() {
|
|||
const { foreignBridge } = await deployForeign()
|
||||
console.log('\nDeployment has been completed.\n\n')
|
||||
console.log(
|
||||
`[ Home ] HomeBridge: ${homeBridge.address} at block ${
|
||||
homeBridge.deployedBlockNumber
|
||||
}`
|
||||
`[ Home ] HomeBridge: ${homeBridge.address} at block ${homeBridge.deployedBlockNumber}`
|
||||
)
|
||||
console.log(
|
||||
`[ Foreign ] ForeignBridge: ${foreignBridge.address} at block ${
|
||||
|
|
|
@ -44,7 +44,7 @@ async function deployContract(contractJson, args, { from, network, nonce }) {
|
|||
to: null,
|
||||
privateKey: deploymentPrivateKey,
|
||||
url,
|
||||
gasPrice: gasPrice
|
||||
gasPrice
|
||||
})
|
||||
if (Web3Utils.hexToNumber(tx.status) !== 1) {
|
||||
throw new Error('Tx failed')
|
||||
|
@ -110,7 +110,7 @@ async function sendNodeRequest(url, method, signedData) {
|
|||
})
|
||||
const json = await request.json()
|
||||
if (method === 'eth_sendRawTransaction') {
|
||||
assert.equal(json.result.length, 66, `Tx wasn't sent ${json}`)
|
||||
assert.strictEqual(json.result.length, 66, `Tx wasn't sent ${json}`)
|
||||
}
|
||||
return json.result
|
||||
}
|
||||
|
|
|
@ -14,12 +14,15 @@ const VALIDATORS = env.VALIDATORS.split(' ')
|
|||
const {
|
||||
DEPLOYMENT_ACCOUNT_PRIVATE_KEY,
|
||||
REQUIRED_NUMBER_OF_VALIDATORS,
|
||||
FOREIGN_OWNER_MULTISIG,
|
||||
FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS,
|
||||
FOREIGN_UPGRADEABLE_ADMIN_BRIDGE,
|
||||
FOREIGN_BRIDGE_OWNER,
|
||||
FOREIGN_VALIDATORS_OWNER,
|
||||
FOREIGN_UPGRADEABLE_ADMIN,
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
ERC20_TOKEN_ADDRESS,
|
||||
FOREIGN_GAS_PRICE
|
||||
FOREIGN_GAS_PRICE,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX,
|
||||
HOME_DAILY_LIMIT,
|
||||
HOME_MAX_AMOUNT_PER_TX
|
||||
} = env
|
||||
|
||||
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
|
||||
|
@ -65,7 +68,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToBridgeVForeign.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(
|
||||
Web3Utils.hexToNumber(txUpgradeToBridgeVForeign.status),
|
||||
1,
|
||||
'Transaction Failed'
|
||||
)
|
||||
foreignNonce++
|
||||
|
||||
console.log('\ninitializing Foreign Bridge Validators with following parameters:\n')
|
||||
|
@ -74,7 +81,7 @@ async function deployForeign() {
|
|||
)
|
||||
bridgeValidatorsForeign.options.address = storageValidatorsForeign.options.address
|
||||
const initializeForeignData = await bridgeValidatorsForeign.methods
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, FOREIGN_OWNER_MULTISIG)
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, FOREIGN_VALIDATORS_OWNER)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitializeForeign = await sendRawTxForeign({
|
||||
data: initializeForeignData,
|
||||
|
@ -83,12 +90,12 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitializeForeign.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitializeForeign.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
console.log('\nTransferring ownership of ValidatorsProxy\n')
|
||||
const validatorsForeignOwnershipData = await storageValidatorsForeign.methods
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS)
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txValidatorsForeignOwnershipData = await sendRawTxForeign({
|
||||
data: validatorsForeignOwnershipData,
|
||||
|
@ -97,7 +104,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txValidatorsForeignOwnershipData.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(
|
||||
Web3Utils.hexToNumber(txValidatorsForeignOwnershipData.status),
|
||||
1,
|
||||
'Transaction Failed'
|
||||
)
|
||||
foreignNonce++
|
||||
|
||||
console.log('\ndeploying foreignBridge storage\n')
|
||||
|
@ -132,7 +143,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToForeignBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(
|
||||
Web3Utils.hexToNumber(txUpgradeToForeignBridge.status),
|
||||
1,
|
||||
'Transaction Failed'
|
||||
)
|
||||
foreignNonce++
|
||||
|
||||
console.log('\ninitializing Foreign Bridge with following parameters:\n')
|
||||
|
@ -144,7 +159,11 @@ async function deployForeign() {
|
|||
storageValidatorsForeign.options.address,
|
||||
ERC20_TOKEN_ADDRESS,
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
FOREIGN_GAS_PRICE
|
||||
FOREIGN_GAS_PRICE,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX,
|
||||
HOME_DAILY_LIMIT,
|
||||
HOME_MAX_AMOUNT_PER_TX,
|
||||
FOREIGN_BRIDGE_OWNER
|
||||
)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitializeBridge = await sendRawTxForeign({
|
||||
|
@ -154,11 +173,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitializeBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitializeBridge.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
const bridgeOwnershipData = await foreignBridgeStorage.methods
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN_BRIDGE)
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txBridgeOwnershipData = await sendRawTxForeign({
|
||||
data: bridgeOwnershipData,
|
||||
|
@ -167,7 +186,7 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txBridgeOwnershipData.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txBridgeOwnershipData.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
console.log('\nForeign Deployment Bridge completed\n')
|
||||
|
|
|
@ -15,9 +15,9 @@ const VALIDATORS = env.VALIDATORS.split(' ')
|
|||
const {
|
||||
DEPLOYMENT_ACCOUNT_PRIVATE_KEY,
|
||||
REQUIRED_NUMBER_OF_VALIDATORS,
|
||||
HOME_OWNER_MULTISIG,
|
||||
HOME_UPGRADEABLE_ADMIN_VALIDATORS,
|
||||
HOME_UPGRADEABLE_ADMIN_BRIDGE,
|
||||
HOME_BRIDGE_OWNER,
|
||||
HOME_VALIDATORS_OWNER,
|
||||
HOME_UPGRADEABLE_ADMIN,
|
||||
HOME_DAILY_LIMIT,
|
||||
HOME_MAX_AMOUNT_PER_TX,
|
||||
HOME_MIN_AMOUNT_PER_TX,
|
||||
|
@ -25,7 +25,9 @@ const {
|
|||
HOME_GAS_PRICE,
|
||||
BRIDGEABLE_TOKEN_NAME,
|
||||
BRIDGEABLE_TOKEN_SYMBOL,
|
||||
BRIDGEABLE_TOKEN_DECIMALS
|
||||
BRIDGEABLE_TOKEN_DECIMALS,
|
||||
FOREIGN_DAILY_LIMIT,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX
|
||||
} = env
|
||||
|
||||
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
|
||||
|
@ -59,7 +61,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToBridgeVHome.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txUpgradeToBridgeVHome.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\ninitializing Home Bridge Validators with following parameters:\n')
|
||||
|
@ -68,7 +70,7 @@ async function deployHome() {
|
|||
)
|
||||
bridgeValidatorsHome.options.address = storageValidatorsHome.options.address
|
||||
const initializeData = await bridgeValidatorsHome.methods
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, HOME_OWNER_MULTISIG)
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, HOME_VALIDATORS_OWNER)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitialize = await sendRawTxHome({
|
||||
data: initializeData,
|
||||
|
@ -77,12 +79,12 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitialize.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitialize.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('transferring proxy ownership to multisig for Validators Proxy contract')
|
||||
const proxyDataTransfer = await storageValidatorsHome.methods
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN_VALIDATORS)
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN)
|
||||
.encodeABI()
|
||||
const txProxyDataTransfer = await sendRawTxHome({
|
||||
data: proxyDataTransfer,
|
||||
|
@ -91,7 +93,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txProxyDataTransfer.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txProxyDataTransfer.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\ndeploying homeBridge storage\n')
|
||||
|
@ -121,7 +123,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToHomeBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txUpgradeToHomeBridge.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\n[Home] deploying Bridgeble token')
|
||||
|
@ -144,7 +146,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(setBridgeContract.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(setBridgeContract.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('transferring ownership of Bridgeble token to homeBridge contract')
|
||||
|
@ -158,7 +160,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txOwnership.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txOwnership.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\ninitializing Home Bridge with following parameters:\n')
|
||||
|
@ -181,7 +183,10 @@ async function deployHome() {
|
|||
HOME_MIN_AMOUNT_PER_TX,
|
||||
HOME_GAS_PRICE,
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
erc677token.options.address
|
||||
erc677token.options.address,
|
||||
FOREIGN_DAILY_LIMIT,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX,
|
||||
HOME_BRIDGE_OWNER
|
||||
)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitializeHomeBridge = await sendRawTxHome({
|
||||
|
@ -191,12 +196,12 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitializeHomeBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitializeHomeBridge.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('transferring proxy ownership to multisig for Home bridge Proxy contract')
|
||||
const homeBridgeProxyData = await homeBridgeStorage.methods
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN_BRIDGE)
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN)
|
||||
.encodeABI()
|
||||
const txhomeBridgeProxyData = await sendRawTxHome({
|
||||
data: homeBridgeProxyData,
|
||||
|
@ -205,7 +210,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txhomeBridgeProxyData.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txhomeBridgeProxyData.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\nHome Deployment Bridge completed\n')
|
||||
|
@ -213,7 +218,7 @@ async function deployHome() {
|
|||
homeBridge: {
|
||||
address: homeBridgeStorage.options.address,
|
||||
deployedBlockNumber: Web3Utils.hexToNumber(homeBridgeStorage.deployedBlockNumber)
|
||||
},
|
||||
},
|
||||
erc677: { address: erc677token.options.address }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,14 @@ const {
|
|||
DEPLOYMENT_ACCOUNT_PRIVATE_KEY,
|
||||
REQUIRED_NUMBER_OF_VALIDATORS,
|
||||
FOREIGN_GAS_PRICE,
|
||||
FOREIGN_OWNER_MULTISIG,
|
||||
FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS,
|
||||
FOREIGN_UPGRADEABLE_ADMIN_BRIDGE,
|
||||
FOREIGN_BRIDGE_OWNER,
|
||||
FOREIGN_VALIDATORS_OWNER,
|
||||
FOREIGN_UPGRADEABLE_ADMIN,
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
ERC20_TOKEN_ADDRESS
|
||||
ERC20_TOKEN_ADDRESS,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX,
|
||||
HOME_DAILY_LIMIT,
|
||||
HOME_MAX_AMOUNT_PER_TX
|
||||
} = env
|
||||
|
||||
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
|
||||
|
@ -65,7 +68,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToBridgeVForeign.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(
|
||||
Web3Utils.hexToNumber(txUpgradeToBridgeVForeign.status),
|
||||
1,
|
||||
'Transaction Failed'
|
||||
)
|
||||
foreignNonce++
|
||||
|
||||
console.log('\ninitializing Foreign Bridge Validators with following parameters:\n')
|
||||
|
@ -74,7 +81,7 @@ async function deployForeign() {
|
|||
)
|
||||
bridgeValidatorsForeign.options.address = storageValidatorsForeign.options.address
|
||||
const initializeForeignData = await bridgeValidatorsForeign.methods
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, FOREIGN_OWNER_MULTISIG)
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, FOREIGN_VALIDATORS_OWNER)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitializeForeign = await sendRawTxForeign({
|
||||
data: initializeForeignData,
|
||||
|
@ -83,12 +90,12 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitializeForeign.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitializeForeign.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
console.log('\nTransferring ownership of ValidatorsProxy\n')
|
||||
const validatorsForeignOwnershipData = await storageValidatorsForeign.methods
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS)
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txValidatorsForeignOwnershipData = await sendRawTxForeign({
|
||||
data: validatorsForeignOwnershipData,
|
||||
|
@ -97,7 +104,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txValidatorsForeignOwnershipData.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(
|
||||
Web3Utils.hexToNumber(txValidatorsForeignOwnershipData.status),
|
||||
1,
|
||||
'Transaction Failed'
|
||||
)
|
||||
foreignNonce++
|
||||
|
||||
console.log('\ndeploying foreignBridge storage\n')
|
||||
|
@ -132,7 +143,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToForeignBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(
|
||||
Web3Utils.hexToNumber(txUpgradeToForeignBridge.status),
|
||||
1,
|
||||
'Transaction Failed'
|
||||
)
|
||||
foreignNonce++
|
||||
|
||||
console.log('\ninitializing Foreign Bridge with following parameters:\n')
|
||||
|
@ -144,7 +159,11 @@ async function deployForeign() {
|
|||
storageValidatorsForeign.options.address,
|
||||
ERC20_TOKEN_ADDRESS,
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
FOREIGN_GAS_PRICE
|
||||
FOREIGN_GAS_PRICE,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX,
|
||||
HOME_DAILY_LIMIT,
|
||||
HOME_MAX_AMOUNT_PER_TX,
|
||||
FOREIGN_BRIDGE_OWNER
|
||||
)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitializeBridge = await sendRawTxForeign({
|
||||
|
@ -154,11 +173,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitializeBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitializeBridge.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
const bridgeOwnershipData = await foreignBridgeStorage.methods
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN_BRIDGE)
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txBridgeOwnershipData = await sendRawTxForeign({
|
||||
data: bridgeOwnershipData,
|
||||
|
@ -167,7 +186,7 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txBridgeOwnershipData.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txBridgeOwnershipData.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
console.log('\nForeign Deployment Bridge completed\n')
|
||||
|
|
|
@ -16,13 +16,15 @@ const {
|
|||
DEPLOYMENT_ACCOUNT_PRIVATE_KEY,
|
||||
REQUIRED_NUMBER_OF_VALIDATORS,
|
||||
HOME_GAS_PRICE,
|
||||
HOME_OWNER_MULTISIG,
|
||||
HOME_UPGRADEABLE_ADMIN_VALIDATORS,
|
||||
HOME_UPGRADEABLE_ADMIN_BRIDGE,
|
||||
HOME_BRIDGE_OWNER,
|
||||
HOME_VALIDATORS_OWNER,
|
||||
HOME_UPGRADEABLE_ADMIN,
|
||||
HOME_DAILY_LIMIT,
|
||||
HOME_MAX_AMOUNT_PER_TX,
|
||||
HOME_MIN_AMOUNT_PER_TX,
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
FOREIGN_DAILY_LIMIT,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX
|
||||
} = env
|
||||
|
||||
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
|
||||
|
@ -56,7 +58,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToBridgeVHome.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txUpgradeToBridgeVHome.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\ninitializing Home Bridge Validators with following parameters:\n')
|
||||
|
@ -65,7 +67,7 @@ async function deployHome() {
|
|||
)
|
||||
bridgeValidatorsHome.options.address = storageValidatorsHome.options.address
|
||||
const initializeData = await bridgeValidatorsHome.methods
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, HOME_OWNER_MULTISIG)
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, HOME_VALIDATORS_OWNER)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitialize = await sendRawTxHome({
|
||||
data: initializeData,
|
||||
|
@ -74,12 +76,12 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitialize.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitialize.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('transferring proxy ownership to multisig for Validators Proxy contract')
|
||||
const proxyDataTransfer = await storageValidatorsHome.methods
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN_VALIDATORS)
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN)
|
||||
.encodeABI()
|
||||
const txProxyDataTransfer = await sendRawTxHome({
|
||||
data: proxyDataTransfer,
|
||||
|
@ -88,7 +90,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txProxyDataTransfer.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txProxyDataTransfer.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\ndeploying homeBridge storage\n')
|
||||
|
@ -118,7 +120,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToHomeBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txUpgradeToHomeBridge.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\ninitializing Home Bridge with following parameters:\n')
|
||||
|
@ -140,7 +142,10 @@ async function deployHome() {
|
|||
HOME_MIN_AMOUNT_PER_TX,
|
||||
HOME_GAS_PRICE,
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
BLOCK_REWARD_ADDRESS
|
||||
BLOCK_REWARD_ADDRESS,
|
||||
FOREIGN_DAILY_LIMIT,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX,
|
||||
HOME_BRIDGE_OWNER
|
||||
)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitializeHomeBridge = await sendRawTxHome({
|
||||
|
@ -150,12 +155,12 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitializeHomeBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitializeHomeBridge.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('transferring proxy ownership to multisig for Home bridge Proxy contract')
|
||||
const homeBridgeProxyData = await homeBridgeStorage.methods
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN_BRIDGE)
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN)
|
||||
.encodeABI()
|
||||
const txhomeBridgeProxyData = await sendRawTxHome({
|
||||
data: homeBridgeProxyData,
|
||||
|
@ -164,7 +169,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txhomeBridgeProxyData.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txhomeBridgeProxyData.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\nHome Deployment Bridge completed\n')
|
||||
|
|
|
@ -35,18 +35,18 @@ let validations = {
|
|||
FOREIGN_DEPLOYMENT_GAS_PRICE: bigNumValidator(),
|
||||
GET_RECEIPT_INTERVAL_IN_MILLISECONDS: bigNumValidator(),
|
||||
HOME_RPC_URL: envalid.str(),
|
||||
HOME_OWNER_MULTISIG: addressValidator(),
|
||||
HOME_UPGRADEABLE_ADMIN_VALIDATORS: addressesValidator(),
|
||||
HOME_UPGRADEABLE_ADMIN_BRIDGE: addressValidator(),
|
||||
HOME_BRIDGE_OWNER: addressValidator(),
|
||||
HOME_VALIDATORS_OWNER: addressesValidator(),
|
||||
HOME_UPGRADEABLE_ADMIN: addressValidator(),
|
||||
HOME_DAILY_LIMIT: bigNumValidator(),
|
||||
HOME_MAX_AMOUNT_PER_TX: bigNumValidator(),
|
||||
HOME_MIN_AMOUNT_PER_TX: bigNumValidator(),
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS: envalid.num(),
|
||||
HOME_GAS_PRICE: bigNumValidator(),
|
||||
FOREIGN_RPC_URL: envalid.str(),
|
||||
FOREIGN_OWNER_MULTISIG: addressValidator(),
|
||||
FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS: addressValidator(),
|
||||
FOREIGN_UPGRADEABLE_ADMIN_BRIDGE: addressValidator(),
|
||||
FOREIGN_BRIDGE_OWNER: addressValidator(),
|
||||
FOREIGN_VALIDATORS_OWNER: addressValidator(),
|
||||
FOREIGN_UPGRADEABLE_ADMIN: addressValidator(),
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS: envalid.num(),
|
||||
FOREIGN_GAS_PRICE: bigNumValidator(),
|
||||
REQUIRED_NUMBER_OF_VALIDATORS: envalid.num(),
|
||||
|
@ -61,7 +61,10 @@ if (BRIDGE_MODE === 'NATIVE_TO_ERC') {
|
|||
BRIDGEABLE_TOKEN_DECIMALS: envalid.num(),
|
||||
FOREIGN_DAILY_LIMIT: bigNumValidator(),
|
||||
FOREIGN_MAX_AMOUNT_PER_TX: bigNumValidator(),
|
||||
FOREIGN_MIN_AMOUNT_PER_TX: bigNumValidator()
|
||||
FOREIGN_MIN_AMOUNT_PER_TX: bigNumValidator(),
|
||||
DEPLOY_REWARDABLE_TOKEN: envalid.bool(),
|
||||
DPOS_VALIDATOR_SET_ADDRESS: addressValidator(),
|
||||
BLOCK_REWARD_ADDRESS: addressValidator()
|
||||
}
|
||||
}
|
||||
if (BRIDGE_MODE === 'ERC_TO_ERC') {
|
||||
|
|
|
@ -6,6 +6,7 @@ const { deployContract, privateKeyToAddress, sendRawTxForeign } = require('../de
|
|||
const { web3Foreign, deploymentPrivateKey, FOREIGN_RPC_URL } = require('../web3')
|
||||
|
||||
const ERC677BridgeToken = require('../../../build/contracts/ERC677BridgeToken.json')
|
||||
const ERC677BridgeTokenRewardable = require('../../../build/contracts/ERC677BridgeTokenRewardable.json')
|
||||
const EternalStorageProxy = require('../../../build/contracts/EternalStorageProxy.json')
|
||||
const BridgeValidators = require('../../../build/contracts/BridgeValidators.json')
|
||||
const ForeignBridge = require('../../../build/contracts/ForeignBridgeNativeToErc.json')
|
||||
|
@ -16,16 +17,21 @@ const {
|
|||
DEPLOYMENT_ACCOUNT_PRIVATE_KEY,
|
||||
REQUIRED_NUMBER_OF_VALIDATORS,
|
||||
FOREIGN_GAS_PRICE,
|
||||
FOREIGN_OWNER_MULTISIG,
|
||||
FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS,
|
||||
FOREIGN_UPGRADEABLE_ADMIN_BRIDGE,
|
||||
FOREIGN_BRIDGE_OWNER,
|
||||
FOREIGN_VALIDATORS_OWNER,
|
||||
FOREIGN_UPGRADEABLE_ADMIN,
|
||||
FOREIGN_DAILY_LIMIT,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX,
|
||||
FOREIGN_MIN_AMOUNT_PER_TX,
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
BRIDGEABLE_TOKEN_NAME,
|
||||
BRIDGEABLE_TOKEN_SYMBOL,
|
||||
BRIDGEABLE_TOKEN_DECIMALS
|
||||
BRIDGEABLE_TOKEN_DECIMALS,
|
||||
HOME_DAILY_LIMIT,
|
||||
HOME_MAX_AMOUNT_PER_TX,
|
||||
DEPLOY_REWARDABLE_TOKEN,
|
||||
BLOCK_REWARD_ADDRESS,
|
||||
DPOS_VALIDATOR_SET_ADDRESS
|
||||
} = env
|
||||
|
||||
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
|
||||
|
@ -38,7 +44,7 @@ async function deployForeign() {
|
|||
|
||||
console.log('\n[Foreign] deploying BRIDGEABLE_TOKEN_SYMBOL token')
|
||||
const erc677bridgeToken = await deployContract(
|
||||
ERC677BridgeToken,
|
||||
DEPLOY_REWARDABLE_TOKEN ? ERC677BridgeTokenRewardable : ERC677BridgeToken,
|
||||
[BRIDGEABLE_TOKEN_NAME, BRIDGEABLE_TOKEN_SYMBOL, BRIDGEABLE_TOKEN_DECIMALS],
|
||||
{ from: DEPLOYMENT_ACCOUNT_ADDRESS, network: 'foreign', nonce: foreignNonce }
|
||||
)
|
||||
|
@ -77,7 +83,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToBridgeVForeign.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(
|
||||
Web3Utils.hexToNumber(txUpgradeToBridgeVForeign.status),
|
||||
1,
|
||||
'Transaction Failed'
|
||||
)
|
||||
foreignNonce++
|
||||
|
||||
console.log('\ninitializing Foreign Bridge Validators with following parameters:\n')
|
||||
|
@ -86,7 +96,7 @@ async function deployForeign() {
|
|||
)
|
||||
bridgeValidatorsForeign.options.address = storageValidatorsForeign.options.address
|
||||
const initializeForeignData = await bridgeValidatorsForeign.methods
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, FOREIGN_OWNER_MULTISIG)
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, FOREIGN_VALIDATORS_OWNER)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitializeForeign = await sendRawTxForeign({
|
||||
data: initializeForeignData,
|
||||
|
@ -95,12 +105,12 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitializeForeign.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitializeForeign.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
console.log('\nTransferring ownership of ValidatorsProxy\n')
|
||||
const validatorsForeignOwnershipData = await storageValidatorsForeign.methods
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS)
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txValidatorsForeignOwnershipData = await sendRawTxForeign({
|
||||
data: validatorsForeignOwnershipData,
|
||||
|
@ -109,7 +119,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txValidatorsForeignOwnershipData.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(
|
||||
Web3Utils.hexToNumber(txValidatorsForeignOwnershipData.status),
|
||||
1,
|
||||
'Transaction Failed'
|
||||
)
|
||||
foreignNonce++
|
||||
|
||||
console.log('\ndeploying foreignBridge storage\n')
|
||||
|
@ -144,7 +158,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToForeignBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(
|
||||
Web3Utils.hexToNumber(txUpgradeToForeignBridge.status),
|
||||
1,
|
||||
'Transaction Failed'
|
||||
)
|
||||
foreignNonce++
|
||||
|
||||
console.log('\ninitializing Foreign Bridge with following parameters:\n')
|
||||
|
@ -168,7 +186,10 @@ async function deployForeign() {
|
|||
FOREIGN_MAX_AMOUNT_PER_TX,
|
||||
FOREIGN_MIN_AMOUNT_PER_TX,
|
||||
FOREIGN_GAS_PRICE,
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
HOME_DAILY_LIMIT,
|
||||
HOME_MAX_AMOUNT_PER_TX,
|
||||
FOREIGN_BRIDGE_OWNER
|
||||
)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitializeBridge = await sendRawTxForeign({
|
||||
|
@ -178,7 +199,7 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitializeBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitializeBridge.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
console.log('\nset bridge contract on ERC677BridgeToken')
|
||||
|
@ -192,9 +213,39 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(setBridgeContract.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(setBridgeContract.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
if (DEPLOY_REWARDABLE_TOKEN) {
|
||||
console.log('\nset BlockReward contract on ERC677BridgeTokenRewardable')
|
||||
const setBlockRewardContractData = await erc677bridgeToken.methods
|
||||
.setBlockRewardContract(BLOCK_REWARD_ADDRESS)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const setBlockRewardContract = await sendRawTxForeign({
|
||||
data: setBlockRewardContractData,
|
||||
nonce: foreignNonce,
|
||||
to: erc677bridgeToken.options.address,
|
||||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(setBlockRewardContract.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
console.log('\nset ValidatorSet contract on ERC677BridgeTokenRewardable')
|
||||
const setValidatorSetContractData = await erc677bridgeToken.methods
|
||||
.setValidatorSetContract(DPOS_VALIDATOR_SET_ADDRESS)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const setValidatorSetContract = await sendRawTxForeign({
|
||||
data: setValidatorSetContractData,
|
||||
nonce: foreignNonce,
|
||||
to: erc677bridgeToken.options.address,
|
||||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(setValidatorSetContract.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
}
|
||||
|
||||
console.log('transferring ownership of ERC677BridgeToken token to foreignBridge contract')
|
||||
const txOwnershipData = await erc677bridgeToken.methods
|
||||
.transferOwnership(foreignBridgeStorage.options.address)
|
||||
|
@ -206,11 +257,11 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txOwnership.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txOwnership.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
const bridgeOwnershipData = await foreignBridgeStorage.methods
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN_BRIDGE)
|
||||
.transferProxyOwnership(FOREIGN_UPGRADEABLE_ADMIN)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txBridgeOwnershipData = await sendRawTxForeign({
|
||||
data: bridgeOwnershipData,
|
||||
|
@ -219,7 +270,7 @@ async function deployForeign() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txBridgeOwnershipData.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txBridgeOwnershipData.status), 1, 'Transaction Failed')
|
||||
foreignNonce++
|
||||
|
||||
console.log('\nForeign Deployment Bridge completed\n')
|
||||
|
|
|
@ -15,13 +15,15 @@ const {
|
|||
DEPLOYMENT_ACCOUNT_PRIVATE_KEY,
|
||||
REQUIRED_NUMBER_OF_VALIDATORS,
|
||||
HOME_GAS_PRICE,
|
||||
HOME_OWNER_MULTISIG,
|
||||
HOME_UPGRADEABLE_ADMIN_VALIDATORS,
|
||||
HOME_UPGRADEABLE_ADMIN_BRIDGE,
|
||||
HOME_BRIDGE_OWNER,
|
||||
HOME_VALIDATORS_OWNER,
|
||||
HOME_UPGRADEABLE_ADMIN,
|
||||
HOME_DAILY_LIMIT,
|
||||
HOME_MAX_AMOUNT_PER_TX,
|
||||
HOME_MIN_AMOUNT_PER_TX,
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
FOREIGN_DAILY_LIMIT,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX
|
||||
} = env
|
||||
|
||||
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
|
||||
|
@ -55,7 +57,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToBridgeVHome.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txUpgradeToBridgeVHome.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\ninitializing Home Bridge Validators with following parameters:\n')
|
||||
|
@ -64,7 +66,7 @@ async function deployHome() {
|
|||
)
|
||||
bridgeValidatorsHome.options.address = storageValidatorsHome.options.address
|
||||
const initializeData = await bridgeValidatorsHome.methods
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, HOME_OWNER_MULTISIG)
|
||||
.initialize(REQUIRED_NUMBER_OF_VALIDATORS, VALIDATORS, HOME_VALIDATORS_OWNER)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitialize = await sendRawTxHome({
|
||||
data: initializeData,
|
||||
|
@ -73,12 +75,12 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitialize.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitialize.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('transferring proxy ownership to multisig for Validators Proxy contract')
|
||||
const proxyDataTransfer = await storageValidatorsHome.methods
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN_VALIDATORS)
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN)
|
||||
.encodeABI()
|
||||
const txProxyDataTransfer = await sendRawTxHome({
|
||||
data: proxyDataTransfer,
|
||||
|
@ -87,7 +89,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txProxyDataTransfer.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txProxyDataTransfer.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\ndeploying homeBridge storage\n')
|
||||
|
@ -117,7 +119,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txUpgradeToHomeBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txUpgradeToHomeBridge.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\ninitializing Home Bridge with following parameters:\n')
|
||||
|
@ -139,7 +141,10 @@ async function deployHome() {
|
|||
HOME_MAX_AMOUNT_PER_TX,
|
||||
HOME_MIN_AMOUNT_PER_TX,
|
||||
HOME_GAS_PRICE,
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS,
|
||||
FOREIGN_DAILY_LIMIT,
|
||||
FOREIGN_MAX_AMOUNT_PER_TX,
|
||||
HOME_BRIDGE_OWNER
|
||||
)
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
const txInitializeHomeBridge = await sendRawTxHome({
|
||||
|
@ -149,12 +154,12 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txInitializeHomeBridge.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txInitializeHomeBridge.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('transferring proxy ownership to multisig for Home bridge Proxy contract')
|
||||
const homeBridgeProxyData = await homeBridgeStorage.methods
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN_BRIDGE)
|
||||
.transferProxyOwnership(HOME_UPGRADEABLE_ADMIN)
|
||||
.encodeABI()
|
||||
const txhomeBridgeProxyData = await sendRawTxHome({
|
||||
data: homeBridgeProxyData,
|
||||
|
@ -163,7 +168,7 @@ async function deployHome() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: HOME_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txhomeBridgeProxyData.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txhomeBridgeProxyData.status), 1, 'Transaction Failed')
|
||||
homeNonce++
|
||||
|
||||
console.log('\nHome Deployment Bridge completed\n')
|
||||
|
|
|
@ -38,11 +38,11 @@ async function deployToken() {
|
|||
privateKey: deploymentPrivateKey,
|
||||
url: FOREIGN_RPC_URL
|
||||
})
|
||||
assert.equal(Web3Utils.hexToNumber(txMint.status), 1, 'Transaction Failed')
|
||||
assert.strictEqual(Web3Utils.hexToNumber(txMint.status), 1, 'Transaction Failed')
|
||||
|
||||
console.log('\nToken deployment is completed\n')
|
||||
return {
|
||||
erc677tokenAddress: erc677token.options.address,
|
||||
erc677tokenAddress: erc677token.options.address
|
||||
}
|
||||
}
|
||||
module.exports = deployToken
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
const env = require('./src/loadEnv')
|
||||
|
||||
const deployToken = require('./src/utils/deployERC20Token')
|
||||
|
||||
const mode = process.argv[2]
|
||||
|
||||
async function main() {
|
||||
switch(mode) {
|
||||
switch (mode) {
|
||||
case 'token':
|
||||
await deployToken()
|
||||
break
|
||||
|
|
|
@ -9,6 +9,10 @@ const {createMessage, sign, signatureToVRS} = require('../helpers/helpers');
|
|||
const halfEther = web3.toBigNumber(web3.toWei(0.5, "ether"));
|
||||
const requireBlockConfirmations = 8;
|
||||
const gasPrice = web3.toWei('1', 'gwei')
|
||||
const oneEther = web3.toBigNumber(web3.toWei(1, "ether"));
|
||||
const homeDailyLimit = oneEther
|
||||
const homeMaxPerTx = halfEther
|
||||
const maxPerTx = halfEther
|
||||
|
||||
contract('ForeignBridge_ERC20_to_ERC20', async (accounts) => {
|
||||
let validatorContract, authorities, owner, token;
|
||||
|
@ -30,16 +34,16 @@ contract('ForeignBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
false.should.be.equal(await foreignBridge.isInitialized())
|
||||
'0'.should.be.bignumber.equal(await foreignBridge.requiredBlockConfirmations())
|
||||
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations).should.be.rejectedWith(INVALID_ARGUMENTS);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, owner).should.be.rejectedWith(INVALID_ARGUMENTS);
|
||||
|
||||
await foreignBridge.initialize(ZERO_ADDRESS, token.address, requireBlockConfirmations, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, ZERO_ADDRESS, requireBlockConfirmations, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, owner, requireBlockConfirmations, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, 0, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, 0).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(owner, token.address, requireBlockConfirmations, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(ZERO_ADDRESS, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, ZERO_ADDRESS, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, owner, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, 0, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, 0, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(owner, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner);
|
||||
|
||||
token.address.should.be.equal(await foreignBridge.erc20token());
|
||||
true.should.be.equal(await foreignBridge.isInitialized())
|
||||
|
@ -61,10 +65,11 @@ contract('ForeignBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
|
||||
describe('#executeSignatures', async () => {
|
||||
var value = web3.toBigNumber(web3.toWei(0.25, "ether"));
|
||||
let foreignBridge
|
||||
beforeEach(async () => {
|
||||
foreignBridge = await ForeignBridge.new()
|
||||
token = await ERC677BridgeToken.new("Some ERC20", "RSZT", 18);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner);
|
||||
await token.mint(foreignBridge.address,value);
|
||||
})
|
||||
it('should allow to executeSignatures', async () => {
|
||||
|
@ -134,6 +139,45 @@ contract('ForeignBridge_ERC20_to_ERC20', 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"));
|
||||
await token.mint(foreignBridge.address, web3.toBigNumber(web3.toWei(5, "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];
|
||||
await token.mint(foreignBridge.address, web3.toBigNumber(web3.toWei(5, "ether")));
|
||||
|
||||
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('#withdraw with 2 minimum signatures', async () => {
|
||||
|
@ -148,7 +192,7 @@ contract('ForeignBridge_ERC20_to_ERC20', 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, requireBlockConfirmations, gasPrice, {from: ownerOfValidatorContract});
|
||||
await foreignBridgeWithMultiSignatures.initialize(multisigValidatorContract.address, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner, {from: ownerOfValidatorContract});
|
||||
await token.mint(foreignBridgeWithMultiSignatures.address,value);
|
||||
})
|
||||
it('withdraw should fail if not enough signatures are provided', async () => {
|
||||
|
@ -192,7 +236,7 @@ contract('ForeignBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
const value = web3.toBigNumber(web3.toWei(0.5, "ether"));
|
||||
const foreignBridgeWithThreeSigs = await ForeignBridge.new()
|
||||
|
||||
await foreignBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, erc20Token.address, requireBlockConfirmations, gasPrice);
|
||||
await foreignBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, erc20Token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner);
|
||||
await erc20Token.mint(foreignBridgeWithThreeSigs.address, value);
|
||||
|
||||
const txHash = "0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121";
|
||||
|
@ -241,7 +285,7 @@ contract('ForeignBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
await foreignBridgeProxy.upgradeTo('1', foreignBridgeImpl.address).should.be.fulfilled;
|
||||
|
||||
foreignBridgeProxy = await ForeignBridge.at(foreignBridgeProxy.address);
|
||||
await foreignBridgeProxy.initialize(validatorsProxy.address, token.address, requireBlockConfirmations, gasPrice)
|
||||
await foreignBridgeProxy.initialize(validatorsProxy.address, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner)
|
||||
|
||||
// Deploy V2
|
||||
let foreignImplV2 = await ForeignBridgeV2.new();
|
||||
|
@ -261,7 +305,7 @@ contract('ForeignBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
let storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
|
||||
let foreignBridge = await ForeignBridge.new();
|
||||
let data = foreignBridge.initialize.request(
|
||||
validatorsAddress, tokenAddress, requireBlockConfirmations, gasPrice).params[0].data
|
||||
validatorsAddress, tokenAddress, requireBlockConfirmations, gasPrice, maxPerTx, 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());
|
||||
|
@ -273,8 +317,11 @@ contract('ForeignBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
it('can send erc20', async () => {
|
||||
const owner = accounts[0];
|
||||
token = await ERC677BridgeToken.new("Some ERC20", "RSZT", 18);
|
||||
foreignBridge = await ForeignBridge.new();
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice);
|
||||
const foreignBridgeImpl = await ForeignBridge.new();
|
||||
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, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner);
|
||||
|
||||
let tokenSecond = await ERC677BridgeToken.new("Roman Token", "RST", 18);
|
||||
|
||||
|
|
|
@ -10,6 +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
|
||||
|
||||
|
||||
contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
||||
|
@ -31,7 +33,7 @@ contract('HomeBridge_ERC20_to_ERC20', 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, token.address).should.be.fulfilled;
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address, 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);
|
||||
|
@ -48,14 +50,14 @@ contract('HomeBridge_ERC20_to_ERC20', 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, token.address).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '2', gasPrice, requireBlockConfirmations, token.address).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '1', '2', '1', gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '2', gasPrice, requireBlockConfirmations, token.address, 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, token.address).params[0].data
|
||||
let data = homeContract.initialize.request(validatorContract.address, "3", "2", "1", gasPrice, requireBlockConfirmations, token.address, 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());
|
||||
|
@ -67,13 +69,14 @@ contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
|
||||
it('cant initialize with invalid arguments', async () => {
|
||||
false.should.be.equal(await homeContract.isInitialized())
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', 0, requireBlockConfirmations, token.address).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, 0, token.address).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(owner, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(ZERO_ADDRESS, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, ZERO_ADDRESS).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address).should.be.fulfilled;
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', 0, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, 0, token.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(owner, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(ZERO_ADDRESS, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, ZERO_ADDRESS, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, owner, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address, halfEther, oneEther, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.fulfilled;
|
||||
true.should.be.equal(await homeContract.isInitialized())
|
||||
})
|
||||
})
|
||||
|
@ -82,7 +85,7 @@ contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
beforeEach(async () => {
|
||||
homeContract = await HomeBridge.new()
|
||||
token = await ERC677BridgeToken.new("Some ERC20", "RSZT", 18);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address)
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner)
|
||||
})
|
||||
it('reverts', async () => {
|
||||
const {logs} = await homeContract.sendTransaction({
|
||||
|
@ -97,7 +100,7 @@ contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
beforeEach(async () => {
|
||||
homeContract = await HomeBridge.new()
|
||||
token = await ERC677BridgeToken.new("Some ERC20", "RSZT", 18);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address)
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, token.address, 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);
|
||||
|
@ -119,7 +122,7 @@ contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
beforeEach(async () => {
|
||||
homeBridge = await HomeBridge.new();
|
||||
token = await ERC677BridgeToken.new("Some ERC20", "RSZT", 18);
|
||||
await homeBridge.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address);
|
||||
await homeBridge.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
await token.transferOwnership(homeBridge.address);
|
||||
})
|
||||
it('should allow validator to withdraw', async () => {
|
||||
|
@ -159,7 +162,7 @@ contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
let ownerOfValidators = accounts[0]
|
||||
await validatorContractWith2Signatures.initialize(2, authoritiesThreeAccs, ownerOfValidators)
|
||||
let homeBridgeWithTwoSigs = await HomeBridge.new();
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token2sig.address);
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token2sig.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
await token2sig.transferOwnership(homeBridgeWithTwoSigs.address);
|
||||
const recipient = accounts[5];
|
||||
const value = halfEther;
|
||||
|
@ -222,7 +225,7 @@ contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
let ownerOfValidators = accounts[0]
|
||||
await validatorContractWith2Signatures.initialize(2, authoritiesThreeAccs, ownerOfValidators)
|
||||
let homeBridgeWithTwoSigs = await HomeBridge.new();
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token2sig.address);
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token2sig.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
await token2sig.transferOwnership(homeBridgeWithTwoSigs.address);
|
||||
const recipient = accounts[5];
|
||||
const value = halfEther.div(2);
|
||||
|
@ -249,7 +252,7 @@ contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
const token = await ERC677BridgeToken.new("Some ERC20", "RSZT", 18);
|
||||
|
||||
const homeBridgeWithThreeSigs = await HomeBridge.new();
|
||||
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address);
|
||||
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
await token.transferOwnership(homeBridgeWithThreeSigs.address);
|
||||
|
||||
const value = web3.toBigNumber(web3.toWei(0.5, "ether"));
|
||||
|
@ -272,6 +275,95 @@ contract('HomeBridge_ERC20_to_ERC20', 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";
|
||||
const {logs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled;
|
||||
|
||||
logs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
logs[0].args.should.be.deep.equal({
|
||||
recipient,
|
||||
value,
|
||||
transactionHash
|
||||
});
|
||||
})
|
||||
it('should fail if txHash already set as above of limits', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
const {logs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled;
|
||||
|
||||
logs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
logs[0].args.should.be.deep.equal({
|
||||
recipient,
|
||||
value,
|
||||
transactionHash
|
||||
});
|
||||
|
||||
await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.rejectedWith(ERROR_MSG)
|
||||
await homeBridge.executeAffirmation(accounts[6], value, transactionHash, {from: authorities[0]}).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
it('should not allow execute affirmation over daily foreign limit', async () => {
|
||||
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";
|
||||
const { logs: logs3 } = await homeBridge.executeAffirmation(recipient, value, transactionHash3, {from: authorities[0]}).should.be.fulfilled;
|
||||
|
||||
logs3[0].event.should.be.equal("AmountLimitExceeded");
|
||||
logs3[0].args.should.be.deep.equal({
|
||||
recipient,
|
||||
value,
|
||||
transactionHash: transactionHash3
|
||||
});
|
||||
|
||||
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
|
||||
outOfLimitAmount.should.be.bignumber.equal(halfEther)
|
||||
|
||||
const transactionHash4 = "0xc9ffe298d85ec5c515153608924b7bdcf1835539813dcc82cdbcc071170c3196";
|
||||
const { logs: logs4 } = await homeBridge.executeAffirmation(recipient, value, transactionHash4, {from: authorities[0]}).should.be.fulfilled;
|
||||
|
||||
logs4[0].event.should.be.equal("AmountLimitExceeded");
|
||||
logs4[0].args.should.be.deep.equal({
|
||||
recipient,
|
||||
value,
|
||||
transactionHash: transactionHash4
|
||||
});
|
||||
|
||||
const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
newOutOfLimitAmount.should.be.bignumber.equal(oneEther)
|
||||
})
|
||||
})
|
||||
describe('#isAlreadyProcessed', async () => {
|
||||
it('returns ', async () => {
|
||||
|
@ -293,7 +385,7 @@ contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
ownerOfValidators = accounts[0]
|
||||
await validatorContractWith2Signatures.initialize(2, authoritiesThreeAccs, ownerOfValidators)
|
||||
homeBridgeWithTwoSigs = await HomeBridge.new();
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token2sig.address);
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token2sig.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
await token2sig.transferOwnership(homeBridgeWithTwoSigs.address);
|
||||
})
|
||||
it('allows a validator to submit a signature', async () => {
|
||||
|
@ -343,7 +435,7 @@ contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
const token = await ERC677BridgeToken.new("Some ERC20", "RSZT", 18);
|
||||
|
||||
const homeBridgeWithThreeSigs = await HomeBridge.new();
|
||||
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address);
|
||||
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
|
||||
const value = web3.toBigNumber(web3.toWei(0.5, "ether"));
|
||||
const transactionHash = "0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80";
|
||||
|
@ -411,4 +503,120 @@ contract('HomeBridge_ERC20_to_ERC20', async (accounts) => {
|
|||
'104'.should.be.bignumber.equal(requiredMessageLength)
|
||||
})
|
||||
})
|
||||
|
||||
describe('#fixAssetsAboveLimits', async () => {
|
||||
let homeBridge;
|
||||
const zeroValue = web3.toBigNumber(web3.toWei(0, "ether"))
|
||||
beforeEach(async () => {
|
||||
const homeBridgeImpl = await HomeBridge.new();
|
||||
const storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
|
||||
await storageProxy.upgradeTo('1', homeBridgeImpl.address).should.be.fulfilled
|
||||
homeBridge = await HomeBridge.at(storageProxy.address);
|
||||
await homeBridge.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, token.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.fulfilled
|
||||
})
|
||||
it('Should reduce outOfLimitAmount and not emit any event', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
const {logs: affirmationLogs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled
|
||||
|
||||
affirmationLogs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
|
||||
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
outOfLimitAmount.should.be.bignumber.equal(value)
|
||||
|
||||
const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, false).should.be.fulfilled
|
||||
|
||||
logs.length.should.be.equal(0)
|
||||
|
||||
const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
newOutOfLimitAmount.should.be.bignumber.equal(zeroValue)
|
||||
})
|
||||
it('Should reduce outOfLimitAmount and emit UserRequestForSignature', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
const {logs: affirmationLogs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled
|
||||
|
||||
affirmationLogs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
|
||||
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
outOfLimitAmount.should.be.bignumber.equal(value)
|
||||
|
||||
const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, true).should.be.fulfilled
|
||||
|
||||
logs.length.should.be.equal(1)
|
||||
logs[0].event.should.be.equal('UserRequestForSignature')
|
||||
logs[0].args.should.be.deep.equal({
|
||||
recipient,
|
||||
value
|
||||
})
|
||||
|
||||
const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
newOutOfLimitAmount.should.be.bignumber.equal(zeroValue)
|
||||
})
|
||||
it('Should not be allow to be called by an already fixed txHash', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
const transactionHash2 = "0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121";
|
||||
|
||||
await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled
|
||||
await homeBridge.executeAffirmation(recipient, value, transactionHash2, {from: authorities[0]}).should.be.fulfilled
|
||||
|
||||
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
outOfLimitAmount.should.be.bignumber.equal(value.add(value))
|
||||
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash, false).should.be.fulfilled
|
||||
|
||||
const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
newOutOfLimitAmount.should.be.bignumber.equal(value)
|
||||
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash, false).should.be.rejectedWith(ERROR_MSG)
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash2, false).should.be.fulfilled
|
||||
|
||||
const updatedOutOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
updatedOutOfLimitAmount.should.be.bignumber.equal(zeroValue)
|
||||
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash2, false).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
it('Should fail if txHash didnt increase out of limit amount', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
const invalidTxHash = "0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121";
|
||||
|
||||
const {logs: affirmationLogs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled
|
||||
|
||||
affirmationLogs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
|
||||
await homeBridge.fixAssetsAboveLimits(invalidTxHash, true).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
it('Should fail if not called by proxyOwner', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
|
||||
const {logs: affirmationLogs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled
|
||||
|
||||
affirmationLogs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash, true, { from: recipient}).should.be.rejectedWith(ERROR_MSG)
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash, true, { from: owner}).should.be.fulfilled
|
||||
})
|
||||
})
|
||||
describe('#OwnedUpgradeability', async () => {
|
||||
|
||||
it('upgradeabilityAdmin should return the proxy owner', async () => {
|
||||
const homeBridgeImpl = await HomeBridge.new();
|
||||
const storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
|
||||
await storageProxy.upgradeTo('1', homeBridgeImpl.address).should.be.fulfilled
|
||||
const homeBridge = await HomeBridge.at(storageProxy.address);
|
||||
|
||||
const proxyOwner = await storageProxy.proxyOwner()
|
||||
const upgradeabilityAdmin = await homeBridge.upgradeabilityAdmin()
|
||||
|
||||
upgradeabilityAdmin.should.be.equal(proxyOwner)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -9,6 +9,10 @@ const { createMessage, sign, signatureToVRS } = require('../helpers/helpers');
|
|||
const halfEther = web3.toBigNumber(web3.toWei(0.5, "ether"));
|
||||
const requireBlockConfirmations = 8;
|
||||
const gasPrice = web3.toWei('1', 'gwei');
|
||||
const oneEther = web3.toBigNumber(web3.toWei(1, "ether"));
|
||||
const homeDailyLimit = oneEther
|
||||
const homeMaxPerTx = halfEther
|
||||
const maxPerTx = halfEther
|
||||
|
||||
contract('ForeignBridge_ERC20_to_Native', async (accounts) => {
|
||||
let validatorContract, authorities, owner, token;
|
||||
|
@ -30,14 +34,15 @@ contract('ForeignBridge_ERC20_to_Native', async (accounts) => {
|
|||
false.should.be.equal(await foreignBridge.isInitialized())
|
||||
'0'.should.be.bignumber.equal(await foreignBridge.requiredBlockConfirmations())
|
||||
|
||||
await foreignBridge.initialize(ZERO_ADDRESS, token.address, requireBlockConfirmations, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, ZERO_ADDRESS, requireBlockConfirmations, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, 0, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, 0).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, owner, requireBlockConfirmations, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(owner, token.address, requireBlockConfirmations, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(ZERO_ADDRESS, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, ZERO_ADDRESS, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, 0, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, 0, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, owner, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(owner, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice, maxPerTx, halfEther, homeMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner);
|
||||
|
||||
token.address.should.be.equal(await foreignBridge.erc20token());
|
||||
true.should.be.equal(await foreignBridge.isInitialized())
|
||||
|
@ -63,7 +68,7 @@ contract('ForeignBridge_ERC20_to_Native', async (accounts) => {
|
|||
beforeEach(async () => {
|
||||
foreignBridge = await ForeignBridge.new()
|
||||
token = await ERC677BridgeToken.new("Some ERC20", "RSZT", 18);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner);
|
||||
await token.mint(foreignBridge.address,value);
|
||||
})
|
||||
|
||||
|
@ -143,6 +148,45 @@ contract('ForeignBridge_ERC20_to_Native', async (accounts) => {
|
|||
|
||||
await foreignBridge.executeSignatures([vrs2.v], [vrs2.r], [vrs2.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"));
|
||||
await token.mint(foreignBridge.address, web3.toBigNumber(web3.toWei(5, "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];
|
||||
await token.mint(foreignBridge.address, web3.toBigNumber(web3.toWei(5, "ether")));
|
||||
|
||||
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('#withdraw with 2 minimum signatures', async () => {
|
||||
|
@ -155,7 +199,7 @@ contract('ForeignBridge_ERC20_to_Native', async (accounts) => {
|
|||
ownerOfValidatorContract = accounts[3]
|
||||
await multisigValidatorContract.initialize(2, twoAuthorities, ownerOfValidatorContract, {from: ownerOfValidatorContract})
|
||||
foreignBridgeWithMultiSignatures = await ForeignBridge.new()
|
||||
await foreignBridgeWithMultiSignatures.initialize(multisigValidatorContract.address, token.address, requireBlockConfirmations, gasPrice, {from: ownerOfValidatorContract});
|
||||
await foreignBridgeWithMultiSignatures.initialize(multisigValidatorContract.address, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner, {from: ownerOfValidatorContract});
|
||||
await token.mint(foreignBridgeWithMultiSignatures.address,value);
|
||||
})
|
||||
|
||||
|
@ -203,7 +247,7 @@ contract('ForeignBridge_ERC20_to_Native', async (accounts) => {
|
|||
const value = web3.toBigNumber(web3.toWei(0.5, "ether"));
|
||||
const foreignBridgeWithThreeSigs = await ForeignBridge.new()
|
||||
|
||||
await foreignBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, erc20Token.address, requireBlockConfirmations, gasPrice);
|
||||
await foreignBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, erc20Token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner);
|
||||
await erc20Token.mint(foreignBridgeWithThreeSigs.address, value);
|
||||
|
||||
const txHash = "0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121";
|
||||
|
@ -252,18 +296,13 @@ contract('ForeignBridge_ERC20_to_Native', async (accounts) => {
|
|||
await foreignBridgeProxy.upgradeTo('1', foreignBridgeImpl.address).should.be.fulfilled;
|
||||
|
||||
foreignBridgeProxy = await ForeignBridge.at(foreignBridgeProxy.address);
|
||||
await foreignBridgeProxy.initialize(validatorsProxy.address, token.address, requireBlockConfirmations, gasPrice)
|
||||
await foreignBridgeProxy.initialize(validatorsProxy.address, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner)
|
||||
|
||||
// Deploy V2
|
||||
let foreignImplV2 = await ForeignBridgeV2.new();
|
||||
let foreignBridgeProxyUpgrade = await EternalStorageProxy.at(foreignBridgeProxy.address);
|
||||
await foreignBridgeProxyUpgrade.upgradeTo('2', foreignImplV2.address).should.be.fulfilled;
|
||||
foreignImplV2.address.should.be.equal(await foreignBridgeProxyUpgrade.implementation())
|
||||
|
||||
let foreignBridgeV2Proxy = await ForeignBridgeV2.at(foreignBridgeProxy.address)
|
||||
await foreignBridgeV2Proxy.doSomething(accounts[2], {from: accounts[4]}).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridgeV2Proxy.doSomething(accounts[2], {from: PROXY_OWNER}).should.be.fulfilled;
|
||||
(await foreignBridgeV2Proxy.something()).should.be.equal(accounts[2])
|
||||
})
|
||||
|
||||
it('can be deployed via upgradeToAndCall', async () => {
|
||||
|
@ -272,7 +311,7 @@ contract('ForeignBridge_ERC20_to_Native', async (accounts) => {
|
|||
|
||||
const storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
|
||||
const foreignBridge = await ForeignBridge.new();
|
||||
const data = foreignBridge.initialize.request(validatorsAddress, tokenAddress, requireBlockConfirmations, gasPrice).params[0].data
|
||||
const data = foreignBridge.initialize.request(validatorsAddress, tokenAddress, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner).params[0].data
|
||||
|
||||
await storageProxy.upgradeToAndCall('1', foreignBridge.address, data).should.be.fulfilled;
|
||||
|
||||
|
@ -286,9 +325,12 @@ contract('ForeignBridge_ERC20_to_Native', async (accounts) => {
|
|||
it('can send erc20', async () => {
|
||||
const owner = accounts[0];
|
||||
token = await ERC677BridgeToken.new("Some ERC20", "RSZT", 18);
|
||||
const foreignBridge = await ForeignBridge.new();
|
||||
const foreignBridgeImpl = await ForeignBridge.new();
|
||||
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, requireBlockConfirmations, gasPrice);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, requireBlockConfirmations, gasPrice, maxPerTx, homeDailyLimit, homeMaxPerTx, owner);
|
||||
const tokenSecond = await ERC677BridgeToken.new("Roman Token", "RST", 18);
|
||||
|
||||
await tokenSecond.mint(accounts[0], halfEther).should.be.fulfilled;
|
||||
|
|
|
@ -12,6 +12,9 @@ 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
|
||||
|
||||
|
||||
contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
||||
let homeContract, validatorContract, blockRewardContract, authorities, owner;
|
||||
|
@ -35,7 +38,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
false.should.be.equal(await homeContract.isInitialized())
|
||||
ZERO_ADDRESS.should.be.equal(await homeContract.blockRewardContract())
|
||||
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address).should.be.fulfilled
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.fulfilled
|
||||
|
||||
true.should.be.equal(await homeContract.isInitialized())
|
||||
validatorContract.address.should.be.equal(await homeContract.validatorContract())
|
||||
|
@ -58,7 +61,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
it('can update block reward contract', async () => {
|
||||
ZERO_ADDRESS.should.be.equal(await homeContract.blockRewardContract())
|
||||
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address).should.be.fulfilled
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.fulfilled
|
||||
|
||||
blockRewardContract.address.should.be.equal(await homeContract.blockRewardContract())
|
||||
|
||||
|
@ -81,15 +84,15 @@ contract('HomeBridge_ERC20_to_Native', 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, blockRewardContract.address).should.be.rejectedWith(ERROR_MSG)
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '2', gasPrice, requireBlockConfirmations, blockRewardContract.address).should.be.rejectedWith(ERROR_MSG)
|
||||
await homeContract.initialize(validatorContract.address, '1', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG)
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '2', gasPrice, requireBlockConfirmations, blockRewardContract.address, 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, blockRewardContract.address).params[0].data
|
||||
let data = homeContract.initialize.request(validatorContract.address, "3", "2", "1", gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner).params[0].data
|
||||
|
||||
await storageProxy.upgradeToAndCall('1', homeContract.address, data).should.be.fulfilled
|
||||
let finalContract = await HomeBridge.at(storageProxy.address);
|
||||
|
@ -101,13 +104,44 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
"2".should.be.bignumber.equal(await finalContract.maxPerTx())
|
||||
"1".should.be.bignumber.equal(await finalContract.minPerTx())
|
||||
})
|
||||
it('can be upgraded keeping the state', async () => {
|
||||
const homeOwner = accounts[8]
|
||||
const storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
|
||||
const proxyOwner = await storageProxy.proxyOwner()
|
||||
const data = homeContract.initialize.request(validatorContract.address, "3", "2", "1", gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, homeOwner).params[0].data
|
||||
|
||||
await storageProxy.upgradeToAndCall('1', homeContract.address, data).should.be.fulfilled
|
||||
const finalContract = await HomeBridge.at(storageProxy.address);
|
||||
|
||||
true.should.be.equal(await finalContract.isInitialized())
|
||||
validatorContract.address.should.be.equal(await finalContract.validatorContract())
|
||||
blockRewardContract.address.should.be.equal(await finalContract.blockRewardContract())
|
||||
"3".should.be.bignumber.equal(await finalContract.dailyLimit())
|
||||
"2".should.be.bignumber.equal(await finalContract.maxPerTx())
|
||||
"1".should.be.bignumber.equal(await finalContract.minPerTx())
|
||||
const upgradeabilityAdmin = await finalContract.upgradeabilityAdmin()
|
||||
upgradeabilityAdmin.should.be.equal(proxyOwner)
|
||||
|
||||
const homeContractV2 = await HomeBridge.new()
|
||||
await storageProxy.upgradeTo('2', homeContractV2.address).should.be.fulfilled
|
||||
const finalContractV2 = await HomeBridge.at(storageProxy.address);
|
||||
|
||||
validatorContract.address.should.be.equal(await finalContractV2.validatorContract())
|
||||
blockRewardContract.address.should.be.equal(await finalContractV2.blockRewardContract())
|
||||
"3".should.be.bignumber.equal(await finalContractV2.dailyLimit())
|
||||
"2".should.be.bignumber.equal(await finalContractV2.maxPerTx())
|
||||
"1".should.be.bignumber.equal(await finalContractV2.minPerTx())
|
||||
const upgradeabilityAdminV2 = await finalContractV2.upgradeabilityAdmin()
|
||||
upgradeabilityAdminV2.should.be.equal(proxyOwner)
|
||||
})
|
||||
it('cant initialize with invalid arguments', async () => {
|
||||
false.should.be.equal(await homeContract.isInitialized())
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, 0, blockRewardContract.address).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(owner, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(ZERO_ADDRESS, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address).should.be.fulfilled;
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, 0, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(owner, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(ZERO_ADDRESS, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, owner, foreignDailyLimit, foreignMaxPerTx, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address, halfEther, oneEther, owner).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner).should.be.fulfilled;
|
||||
true.should.be.equal(await homeContract.isInitialized())
|
||||
})
|
||||
})
|
||||
|
@ -115,7 +149,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
describe('#fallback', async () => {
|
||||
beforeEach(async () => {
|
||||
homeContract = await HomeBridge.new()
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address)
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner)
|
||||
})
|
||||
|
||||
it('should accept native coins', async () => {
|
||||
|
@ -246,13 +280,15 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
let homeContract;
|
||||
beforeEach(async () => {
|
||||
homeContract = await HomeBridge.new()
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address)
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, blockRewardContract.address, 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);
|
||||
await homeContract.setMaxPerTx(2, {from: owner}).should.be.fulfilled;
|
||||
|
||||
await homeContract.setMaxPerTx(3, {from: owner}).should.be.rejectedWith(ERROR_MSG);
|
||||
const maxPerTx = await homeContract.maxPerTx()
|
||||
maxPerTx.should.be.bignumber.equal(web3.toBigNumber(2))
|
||||
})
|
||||
|
||||
it('setMinPerTx allows to set only to owner and cannot be more than daily limit and should be less than maxPerTx', async () => {
|
||||
|
@ -260,6 +296,37 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
await homeContract.setMinPerTx(1, {from: owner}).should.be.fulfilled;
|
||||
|
||||
await homeContract.setMinPerTx(2, {from: owner}).should.be.rejectedWith(ERROR_MSG);
|
||||
const minPerTx = await homeContract.minPerTx()
|
||||
minPerTx.should.be.bignumber.equal(web3.toBigNumber(1))
|
||||
})
|
||||
|
||||
it('setExecutionMaxPerTx allows to set only to owner and cannot be more than execution daily limit', async () => {
|
||||
const newValue = web3.toBigNumber(web3.toWei(0.3, "ether"));
|
||||
|
||||
const initialExecutionMaxPerTx = await homeContract.executionMaxPerTx()
|
||||
|
||||
initialExecutionMaxPerTx.should.be.bignumber.not.equal(newValue)
|
||||
|
||||
await homeContract.setExecutionMaxPerTx(newValue, {from: authorities[0]}).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.setExecutionMaxPerTx(newValue, {from: owner}).should.be.fulfilled;
|
||||
|
||||
await homeContract.setExecutionMaxPerTx(oneEther, {from: owner}).should.be.rejectedWith(ERROR_MSG);
|
||||
const executionMaxPerTx = await homeContract.executionMaxPerTx()
|
||||
executionMaxPerTx.should.be.bignumber.equal(newValue)
|
||||
})
|
||||
|
||||
it('executionDailyLimit allows to set only to owner', async () => {
|
||||
const newValue = web3.toBigNumber(web3.toWei(1.5, "ether"));
|
||||
|
||||
const initialExecutionDailyLimit= await homeContract.executionDailyLimit()
|
||||
|
||||
initialExecutionDailyLimit.should.be.bignumber.not.equal(newValue)
|
||||
|
||||
await homeContract.setExecutionDailyLimit(newValue, {from: authorities[0]}).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.setExecutionDailyLimit(newValue, {from: owner}).should.be.fulfilled;
|
||||
|
||||
const executionDailyLimit = await homeContract.executionDailyLimit()
|
||||
executionDailyLimit.should.be.bignumber.equal(newValue)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -267,7 +334,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
let homeBridge;
|
||||
beforeEach(async () => {
|
||||
homeBridge = await HomeBridge.new();
|
||||
await homeBridge.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address);
|
||||
await homeBridge.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
await blockRewardContract.sendTransaction({
|
||||
from: accounts[2],
|
||||
value: oneEther
|
||||
|
@ -306,7 +373,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
const ownerOfValidators = accounts[0]
|
||||
await validatorContractWith2Signatures.initialize(2, authoritiesThreeAccs, ownerOfValidators)
|
||||
const homeBridgeWithTwoSigs = await HomeBridge.new();
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address);
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
const recipient = accounts[5];
|
||||
const value = halfEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
|
@ -348,7 +415,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
|
||||
it('should fail if the block reward contract is not set', async () => {
|
||||
homeBridge = await HomeBridge.new();
|
||||
await homeBridge.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, ZERO_ADDRESS);
|
||||
await homeBridge.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, ZERO_ADDRESS, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
|
||||
const recipient = accounts[5];
|
||||
const value = halfEther;
|
||||
|
@ -363,7 +430,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
|
||||
|
||||
const homeBridgeWithThreeSigs = await HomeBridge.new();
|
||||
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address);
|
||||
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
|
||||
const value = web3.toBigNumber(web3.toWei(0.5, "ether"));
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
|
@ -385,6 +452,100 @@ contract('HomeBridge_ERC20_to_Native', 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";
|
||||
const {logs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled;
|
||||
|
||||
logs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
logs[0].args.should.be.deep.equal({
|
||||
recipient,
|
||||
value,
|
||||
transactionHash
|
||||
});
|
||||
})
|
||||
it('should fail if txHash already set as above of limits', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
const {logs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled;
|
||||
|
||||
logs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
logs[0].args.should.be.deep.equal({
|
||||
recipient,
|
||||
value,
|
||||
transactionHash
|
||||
});
|
||||
|
||||
await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.rejectedWith(ERROR_MSG)
|
||||
await homeBridge.executeAffirmation(accounts[6], value, transactionHash, {from: authorities[0]}).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
it('should not allow execute affirmation over daily foreign limit', async () => {
|
||||
await blockRewardContract.sendTransaction({
|
||||
from: accounts[2],
|
||||
value: oneEther
|
||||
}).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";
|
||||
const { logs: logs3 } = await homeBridge.executeAffirmation(recipient, value, transactionHash3, {from: authorities[0]}).should.be.fulfilled;
|
||||
|
||||
logs3[0].event.should.be.equal("AmountLimitExceeded");
|
||||
logs3[0].args.should.be.deep.equal({
|
||||
recipient,
|
||||
value,
|
||||
transactionHash: transactionHash3
|
||||
});
|
||||
|
||||
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
|
||||
outOfLimitAmount.should.be.bignumber.equal(halfEther)
|
||||
|
||||
const transactionHash4 = "0xc9ffe298d85ec5c515153608924b7bdcf1835539813dcc82cdbcc071170c3196";
|
||||
const { logs: logs4 } = await homeBridge.executeAffirmation(recipient, value, transactionHash4, {from: authorities[0]}).should.be.fulfilled;
|
||||
|
||||
logs4[0].event.should.be.equal("AmountLimitExceeded");
|
||||
logs4[0].args.should.be.deep.equal({
|
||||
recipient,
|
||||
value,
|
||||
transactionHash: transactionHash4
|
||||
});
|
||||
|
||||
const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
newOutOfLimitAmount.should.be.bignumber.equal(oneEther)
|
||||
})
|
||||
})
|
||||
|
||||
describe('#submitSignature', async () => {
|
||||
|
@ -395,7 +556,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
ownerOfValidators = accounts[0]
|
||||
await validatorContractWith2Signatures.initialize(2, authoritiesThreeAccs, ownerOfValidators)
|
||||
homeBridgeWithTwoSigs = await HomeBridge.new();
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address);
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
})
|
||||
|
||||
it('allows a validator to submit a signature', async () => {
|
||||
|
@ -444,7 +605,7 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
|
||||
|
||||
const homeBridgeWithThreeSigs = await HomeBridge.new();
|
||||
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address);
|
||||
await homeBridgeWithThreeSigs.initialize(validatorContractWith3Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
|
||||
const value = web3.toBigNumber(web3.toWei(0.5, "ether"));
|
||||
const transactionHash = "0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80";
|
||||
|
@ -515,6 +676,121 @@ contract('HomeBridge_ERC20_to_Native', async (accounts) => {
|
|||
'104'.should.be.bignumber.equal(requiredMessageLength)
|
||||
})
|
||||
})
|
||||
describe('#fixAssetsAboveLimits', async () => {
|
||||
let homeBridge;
|
||||
const zeroValue = web3.toBigNumber(web3.toWei(0, "ether"))
|
||||
beforeEach(async () => {
|
||||
const homeBridgeImpl = await HomeBridge.new();
|
||||
const storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
|
||||
await storageProxy.upgradeTo('1', homeBridgeImpl.address).should.be.fulfilled
|
||||
homeBridge = await HomeBridge.at(storageProxy.address);
|
||||
await homeBridge.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, blockRewardContract.address, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
})
|
||||
it('Should reduce outOfLimitAmount and not emit any event', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
const {logs: affirmationLogs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled
|
||||
|
||||
affirmationLogs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
|
||||
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
outOfLimitAmount.should.be.bignumber.equal(value)
|
||||
|
||||
const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, false).should.be.fulfilled
|
||||
|
||||
logs.length.should.be.equal(0)
|
||||
|
||||
const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
newOutOfLimitAmount.should.be.bignumber.equal(zeroValue)
|
||||
})
|
||||
it('Should reduce outOfLimitAmount and emit UserRequestForSignature', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
const {logs: affirmationLogs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled
|
||||
|
||||
affirmationLogs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
|
||||
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
outOfLimitAmount.should.be.bignumber.equal(value)
|
||||
|
||||
const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, true).should.be.fulfilled
|
||||
|
||||
logs.length.should.be.equal(1)
|
||||
logs[0].event.should.be.equal('UserRequestForSignature')
|
||||
logs[0].args.should.be.deep.equal({
|
||||
recipient,
|
||||
value
|
||||
})
|
||||
|
||||
const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
newOutOfLimitAmount.should.be.bignumber.equal(zeroValue)
|
||||
})
|
||||
it('Should not be allow to be called by an already fixed txHash', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
const transactionHash2 = "0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121";
|
||||
|
||||
await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled
|
||||
await homeBridge.executeAffirmation(recipient, value, transactionHash2, {from: authorities[0]}).should.be.fulfilled
|
||||
|
||||
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
outOfLimitAmount.should.be.bignumber.equal(value.add(value))
|
||||
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash, false).should.be.fulfilled
|
||||
|
||||
const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
newOutOfLimitAmount.should.be.bignumber.equal(value)
|
||||
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash, false).should.be.rejectedWith(ERROR_MSG)
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash2, false).should.be.fulfilled
|
||||
|
||||
const updatedOutOfLimitAmount = await homeBridge.outOfLimitAmount()
|
||||
updatedOutOfLimitAmount.should.be.bignumber.equal(zeroValue)
|
||||
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash2, false).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
it('Should fail if txHash didnt increase out of limit amount', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
const invalidTxHash = "0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121";
|
||||
|
||||
const {logs: affirmationLogs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled
|
||||
|
||||
affirmationLogs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
|
||||
await homeBridge.fixAssetsAboveLimits(invalidTxHash, true).should.be.rejectedWith(ERROR_MSG)
|
||||
})
|
||||
it('Should fail if not called by proxyOwner', async () => {
|
||||
const recipient = accounts[5];
|
||||
const value = oneEther;
|
||||
const transactionHash = "0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415";
|
||||
|
||||
const {logs: affirmationLogs} = await homeBridge.executeAffirmation(recipient, value, transactionHash, {from: authorities[0]}).should.be.fulfilled
|
||||
|
||||
affirmationLogs[0].event.should.be.equal("AmountLimitExceeded");
|
||||
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash, true, { from: recipient}).should.be.rejectedWith(ERROR_MSG)
|
||||
await homeBridge.fixAssetsAboveLimits(transactionHash, true, { from: owner}).should.be.fulfilled
|
||||
})
|
||||
})
|
||||
describe('#OwnedUpgradeability', async () => {
|
||||
|
||||
it('upgradeabilityAdmin should return the proxy owner', async () => {
|
||||
const homeBridgeImpl = await HomeBridge.new();
|
||||
const storageProxy = await EternalStorageProxy.new().should.be.fulfilled;
|
||||
await storageProxy.upgradeTo('1', homeBridgeImpl.address).should.be.fulfilled
|
||||
const homeBridge = await HomeBridge.at(storageProxy.address);
|
||||
|
||||
const proxyOwner = await storageProxy.proxyOwner()
|
||||
const upgradeabilityAdmin = await homeBridge.upgradeabilityAdmin()
|
||||
|
||||
upgradeabilityAdmin.should.be.equal(proxyOwner)
|
||||
})
|
||||
})
|
||||
|
||||
describe('#feeManager', async () => {
|
||||
let homeBridge, rewardableValidators
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
pragma solidity 0.4.24;
|
||||
|
||||
import '../../contracts/ERC677BridgeTokenRewardable.sol';
|
||||
|
||||
|
||||
contract ERC677BridgeTokenRewardableMock is ERC677BridgeTokenRewardable {
|
||||
|
||||
constructor(
|
||||
string _name,
|
||||
string _symbol,
|
||||
uint8 _decimals
|
||||
) public ERC677BridgeTokenRewardable(_name, _symbol, _decimals) {}
|
||||
|
||||
function setBlockRewardContractMock(address _blockRewardContract) public {
|
||||
blockRewardContract = _blockRewardContract;
|
||||
}
|
||||
|
||||
function setValidatorSetContractMock(address _validatorSetContract) public {
|
||||
validatorSetContract = _validatorSetContract;
|
||||
}
|
||||
|
||||
}
|
|
@ -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).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, ZERO_ADDRESS, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, 0, requireBlockConfirmations).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(owner, token.address, oneEther, halfEther, minPerTx, requireBlockConfirmations, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, owner, oneEther, halfEther, minPerTx, requireBlockConfirmations, gasPrice).should.be.rejectedWith(ERROR_MSG);
|
||||
await foreignBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations);
|
||||
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());
|
||||
|
@ -76,7 +78,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);
|
||||
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);
|
||||
})
|
||||
|
@ -166,6 +168,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 () => {
|
||||
|
@ -179,7 +218,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, {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 () => {
|
||||
|
@ -233,7 +272,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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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)
|
||||
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());
|
||||
|
@ -393,11 +432,6 @@ contract('ForeignBridge', async (accounts) => {
|
|||
let foreignBridgeProxyUpgrade = await EternalStorageProxy.at(foreignBridgeProxy.address);
|
||||
await foreignBridgeProxyUpgrade.upgradeTo('2', foreignImplV2.address).should.be.fulfilled;
|
||||
foreignImplV2.address.should.be.equal(await foreignBridgeProxyUpgrade.implementation())
|
||||
|
||||
let foreignBridgeV2Proxy = await ForeignBridgeV2.at(foreignBridgeProxy.address)
|
||||
await foreignBridgeV2Proxy.changeTokenOwnership(accounts[2], {from: accounts[4]}).should.be.rejectedWith(ERROR_MSG)
|
||||
await foreignBridgeV2Proxy.changeTokenOwnership(accounts[2], {from: PROXY_OWNER}).should.be.fulfilled;
|
||||
await token.transferOwnership(foreignBridgeProxy.address, {from: accounts[2]}).should.be.fulfilled;
|
||||
})
|
||||
it('can be deployed via upgradeToAndCall', async () => {
|
||||
const tokenAddress = token.address
|
||||
|
@ -409,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).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());
|
||||
|
@ -423,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).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
|
||||
})
|
||||
|
@ -433,8 +467,11 @@ contract('ForeignBridge', async (accounts) => {
|
|||
it('can send erc20', async () => {
|
||||
const owner = accounts[0];
|
||||
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);
|
||||
const foreignBridgeImpl = await ForeignBridge.new();
|
||||
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, homeDailyLimit, homeMaxPerTx, owner);
|
||||
await token.transferOwnership(foreignBridge.address)
|
||||
|
||||
let tokenSecond = await POA20.new("Roman Token", "RST", 18);
|
||||
|
@ -453,8 +490,11 @@ contract('ForeignBridge', async (accounts) => {
|
|||
it('also calls claimTokens on tokenAddress', async () => {
|
||||
const owner = accounts[0];
|
||||
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);
|
||||
const foreignBridgeImpl = await ForeignBridge.new();
|
||||
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, 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;
|
||||
|
@ -30,7 +33,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).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);
|
||||
|
@ -47,14 +50,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).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '2', gasPrice, requireBlockConfirmations).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).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());
|
||||
|
@ -65,15 +68,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).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(owner, '3', '2', '1', gasPrice, requireBlockConfirmations).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(ZERO_ADDRESS, '3', '2', '1', gasPrice, requireBlockConfirmations).should.be.rejectedWith(ERROR_MSG);
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations).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).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
|
||||
})
|
||||
|
@ -82,7 +85,7 @@ contract('HomeBridge', async (accounts) => {
|
|||
describe('#fallback', async () => {
|
||||
beforeEach(async () => {
|
||||
homeContract = await HomeBridge.new()
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations)
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner)
|
||||
})
|
||||
it('should accept POA', async () => {
|
||||
const currentDay = await homeContract.getCurrentDay()
|
||||
|
@ -157,7 +160,7 @@ contract('HomeBridge', async (accounts) => {
|
|||
let homeContract;
|
||||
beforeEach(async () => {
|
||||
homeContract = await HomeBridge.new()
|
||||
await homeContract.initialize(validatorContract.address, '3', '2', '1', gasPrice, requireBlockConfirmations)
|
||||
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);
|
||||
|
@ -178,7 +181,7 @@ contract('HomeBridge', async (accounts) => {
|
|||
let homeBridge;
|
||||
beforeEach(async () => {
|
||||
homeBridge = await HomeBridge.new();
|
||||
await homeBridge.initialize(validatorContract.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations);
|
||||
await homeBridge.initialize(validatorContract.address, twoEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
const {logs} = await homeBridge.sendTransaction({
|
||||
from: accounts[2],
|
||||
value: halfEther
|
||||
|
@ -217,7 +220,7 @@ contract('HomeBridge', async (accounts) => {
|
|||
let ownerOfValidators = accounts[0]
|
||||
await validatorContractWith2Signatures.initialize(2, authoritiesThreeAccs, ownerOfValidators)
|
||||
let homeBridgeWithTwoSigs = await HomeBridge.new();
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations);
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, twoEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
|
||||
await homeBridgeWithTwoSigs.sendTransaction({
|
||||
from: accounts[2],
|
||||
|
@ -287,7 +290,7 @@ contract('HomeBridge', async (accounts) => {
|
|||
let ownerOfValidators = accounts[0]
|
||||
await validatorContractWith2Signatures.initialize(2, authoritiesThreeAccs, ownerOfValidators)
|
||||
let homeBridgeWithTwoSigs = await HomeBridge.new();
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations);
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, foreignDailyLimit, foreignMaxPerTx, owner);
|
||||
|
||||
await homeBridgeWithTwoSigs.sendTransaction({
|
||||
from: accounts[2],
|
||||
|
@ -345,7 +348,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);
|
||||
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";
|
||||
|
@ -372,6 +375,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 () => {
|
||||
|
@ -393,7 +443,7 @@ contract('HomeBridge', async (accounts) => {
|
|||
ownerOfValidators = accounts[0]
|
||||
await validatorContractWith2Signatures.initialize(2, authoritiesThreeAccs, ownerOfValidators)
|
||||
homeBridgeWithTwoSigs = await HomeBridge.new();
|
||||
await homeBridgeWithTwoSigs.initialize(validatorContractWith2Signatures.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations);
|
||||
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]
|
||||
|
@ -436,7 +486,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);
|
||||
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";
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
const POA20 = artifacts.require("ERC677BridgeToken.sol");
|
||||
const POA20RewardableMock = artifacts.require("./mockContracts/ERC677BridgeTokenRewardableMock");
|
||||
const ERC677ReceiverTest = artifacts.require("ERC677ReceiverTest.sol")
|
||||
const BlockRewardTest = artifacts.require("BlockReward.sol")
|
||||
const ValidatorSetTest = artifacts.require("ValidatorSet.sol")
|
||||
const { ERROR_MSG, ZERO_ADDRESS} = require('./setup');
|
||||
const Web3Utils = require('web3-utils');
|
||||
const HomeErcToErcBridge = artifacts.require("HomeBridgeErcToErc.sol");
|
||||
|
@ -10,13 +13,16 @@ 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 executionDailyLimit = oneEther
|
||||
const executionMaxPerTx = halfEther
|
||||
|
||||
contract('ERC677BridgeToken', async (accounts) => {
|
||||
async function testERC677BridgeToken(accounts, rewardable) {
|
||||
let token
|
||||
let owner = accounts[0]
|
||||
const user = accounts[1];
|
||||
const tokenContract = rewardable ? POA20RewardableMock : POA20;
|
||||
beforeEach(async () => {
|
||||
token = await POA20.new("POA ERC20 Foundation", "POA20", 18);
|
||||
token = await tokenContract.new("POA ERC20 Foundation", "POA20", 18);
|
||||
})
|
||||
it('default values', async () => {
|
||||
|
||||
|
@ -74,6 +80,160 @@ contract('ERC677BridgeToken', async (accounts) => {
|
|||
})
|
||||
})
|
||||
|
||||
if (rewardable) {
|
||||
describe('#blockRewardContract', async() => {
|
||||
it('can set BlockReward contract', async () => {
|
||||
const blockRewardContract = await BlockRewardTest.new();
|
||||
(await token.blockRewardContract()).should.be.equal(ZERO_ADDRESS);
|
||||
|
||||
await token.setBlockRewardContract(blockRewardContract.address).should.be.fulfilled;
|
||||
|
||||
(await token.blockRewardContract()).should.be.equal(blockRewardContract.address);
|
||||
})
|
||||
|
||||
it('only owner can set BlockReward contract', async () => {
|
||||
const blockRewardContract = await BlockRewardTest.new();
|
||||
(await token.blockRewardContract()).should.be.equal(ZERO_ADDRESS);
|
||||
|
||||
await token.setBlockRewardContract(blockRewardContract.address, {from: user }).should.be.rejectedWith(ERROR_MSG);
|
||||
(await token.blockRewardContract()).should.be.equal(ZERO_ADDRESS);
|
||||
|
||||
await token.setBlockRewardContract(blockRewardContract.address, {from: owner }).should.be.fulfilled;
|
||||
(await token.blockRewardContract()).should.be.equal(blockRewardContract.address);
|
||||
})
|
||||
|
||||
it('fail to set invalid BlockReward contract address', async () => {
|
||||
const invalidContractAddress = '0xaaB52d66283F7A1D5978bcFcB55721ACB467384b';
|
||||
(await token.blockRewardContract()).should.be.equal(ZERO_ADDRESS);
|
||||
|
||||
await token.setBlockRewardContract(invalidContractAddress).should.be.rejectedWith(ERROR_MSG);
|
||||
(await token.blockRewardContract()).should.be.equal(ZERO_ADDRESS);
|
||||
|
||||
await token.setBlockRewardContract(ZERO_ADDRESS).should.be.rejectedWith(ERROR_MSG);
|
||||
(await token.blockRewardContract()).should.be.equal(ZERO_ADDRESS);
|
||||
})
|
||||
})
|
||||
|
||||
describe('#validatorSetContract', async() => {
|
||||
it('can set ValidatorSet contract', async () => {
|
||||
const validatorSetContract = await ValidatorSetTest.new();
|
||||
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
|
||||
|
||||
await token.setValidatorSetContract(validatorSetContract.address).should.be.fulfilled;
|
||||
|
||||
(await token.validatorSetContract()).should.be.equal(validatorSetContract.address);
|
||||
})
|
||||
|
||||
it('only owner can set ValidatorSet contract', async () => {
|
||||
const validatorSetContract = await ValidatorSetTest.new();
|
||||
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
|
||||
|
||||
await token.setValidatorSetContract(validatorSetContract.address, {from: user }).should.be.rejectedWith(ERROR_MSG);
|
||||
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
|
||||
|
||||
await token.setValidatorSetContract(validatorSetContract.address, {from: owner }).should.be.fulfilled;
|
||||
(await token.validatorSetContract()).should.be.equal(validatorSetContract.address);
|
||||
})
|
||||
|
||||
it('fail to set invalid ValidatorSet contract address', async () => {
|
||||
const invalidContractAddress = '0xaaB52d66283F7A1D5978bcFcB55721ACB467384b';
|
||||
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
|
||||
|
||||
await token.setValidatorSetContract(invalidContractAddress).should.be.rejectedWith(ERROR_MSG);
|
||||
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
|
||||
|
||||
await token.setValidatorSetContract(ZERO_ADDRESS).should.be.rejectedWith(ERROR_MSG);
|
||||
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
|
||||
})
|
||||
})
|
||||
|
||||
describe('#mintReward', async() => {
|
||||
it('can only be called by BlockReward contract', async () => {
|
||||
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
|
||||
await token.mintReward([], [], {from: user }).should.be.rejectedWith(ERROR_MSG);
|
||||
await token.mintReward([], [], {from: accounts[2] }).should.be.fulfilled;
|
||||
})
|
||||
it('should increase totalSupply and balances', async () => {
|
||||
const user1 = accounts[1];
|
||||
const user2 = accounts[2];
|
||||
const user3 = accounts[3];
|
||||
|
||||
assert.equal(await token.totalSupply(), 0);
|
||||
(await token.balanceOf(user1)).should.be.bignumber.equal(0);
|
||||
(await token.balanceOf(user2)).should.be.bignumber.equal(0);
|
||||
(await token.balanceOf(user3)).should.be.bignumber.equal(0);
|
||||
|
||||
await token.setBlockRewardContractMock(accounts[4]).should.be.fulfilled;
|
||||
await token.mintReward([user1, user2, user3], [100, 200, 300], {from: accounts[4] }).should.be.fulfilled;
|
||||
|
||||
assert.equal(await token.totalSupply(), 600);
|
||||
(await token.balanceOf(user1)).should.be.bignumber.equal(100);
|
||||
(await token.balanceOf(user2)).should.be.bignumber.equal(200);
|
||||
(await token.balanceOf(user3)).should.be.bignumber.equal(300);
|
||||
})
|
||||
})
|
||||
|
||||
describe('#stake', async() => {
|
||||
it('can only be called by ValidatorSet contract', async () => {
|
||||
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
|
||||
await token.mintReward([user], [100], {from: accounts[2] }).should.be.fulfilled;
|
||||
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
|
||||
await token.stake(user, 100, {from: accounts[4] }).should.be.rejectedWith(ERROR_MSG);
|
||||
await token.stake(user, 100, {from: accounts[3] }).should.be.fulfilled;
|
||||
})
|
||||
it('should revert if user doesn\'t have enough balance', async () => {
|
||||
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
|
||||
await token.mintReward([user], [99], {from: accounts[2] }).should.be.fulfilled;
|
||||
(await token.balanceOf(user)).should.be.bignumber.equal(99);
|
||||
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
|
||||
await token.stake(user, 100, {from: accounts[3] }).should.be.rejectedWith(ERROR_MSG);
|
||||
})
|
||||
it('should decrease user\'s balance and increase ValidatorSet\'s balance', async () => {
|
||||
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
|
||||
await token.mintReward([user], [100], {from: accounts[2] }).should.be.fulfilled;
|
||||
(await token.balanceOf(user)).should.be.bignumber.equal(100);
|
||||
(await token.balanceOf(accounts[3])).should.be.bignumber.equal(0);
|
||||
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
|
||||
await token.stake(user, 100, {from: accounts[3] }).should.be.fulfilled;
|
||||
(await token.balanceOf(user)).should.be.bignumber.equal(0);
|
||||
(await token.balanceOf(accounts[3])).should.be.bignumber.equal(100);
|
||||
})
|
||||
})
|
||||
|
||||
describe('#withdraw', async() => {
|
||||
it('can only be called by ValidatorSet contract', async () => {
|
||||
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
|
||||
await token.mintReward([user], [100], {from: accounts[2] }).should.be.fulfilled;
|
||||
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
|
||||
await token.stake(user, 100, {from: accounts[3] }).should.be.fulfilled;
|
||||
await token.withdraw(user, 100, {from: accounts[4] }).should.be.rejectedWith(ERROR_MSG);
|
||||
await token.withdraw(user, 100, {from: accounts[3] }).should.be.fulfilled;
|
||||
})
|
||||
it('should revert if ValidatorSet doesn\'t have enough balance', async () => {
|
||||
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
|
||||
await token.mintReward([user], [100], {from: accounts[2] }).should.be.fulfilled;
|
||||
(await token.balanceOf(user)).should.be.bignumber.equal(100);
|
||||
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
|
||||
await token.stake(user, 100, {from: accounts[3] }).should.be.fulfilled;
|
||||
await token.withdraw(user, 101, {from: accounts[3] }).should.be.rejectedWith(ERROR_MSG);
|
||||
await token.withdraw(user, 100, {from: accounts[3] }).should.be.fulfilled;
|
||||
})
|
||||
it('should decrease ValidatorSet\'s balance and increase user\'s balance', async () => {
|
||||
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
|
||||
await token.mintReward([user], [100], {from: accounts[2] }).should.be.fulfilled;
|
||||
(await token.balanceOf(user)).should.be.bignumber.equal(100);
|
||||
(await token.balanceOf(accounts[3])).should.be.bignumber.equal(0);
|
||||
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
|
||||
await token.stake(user, 100, {from: accounts[3] }).should.be.fulfilled;
|
||||
(await token.balanceOf(user)).should.be.bignumber.equal(0);
|
||||
(await token.balanceOf(accounts[3])).should.be.bignumber.equal(100);
|
||||
await token.withdraw(user, 60, {from: accounts[3] }).should.be.fulfilled;
|
||||
(await token.balanceOf(user)).should.be.bignumber.equal(60);
|
||||
(await token.balanceOf(accounts[3])).should.be.bignumber.equal(40);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
describe('#mint', async() => {
|
||||
it('can mint by owner', async () => {
|
||||
(await token.totalSupply()).should.be.bignumber.equal(0);
|
||||
|
@ -101,9 +261,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)
|
||||
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);
|
||||
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;
|
||||
|
@ -189,9 +349,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)
|
||||
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);
|
||||
await foreignNativeToErcBridge.initialize(validatorContract.address, token.address, oneEther, halfEther, minPerTx, gasPrice, requireBlockConfirmations, executionDailyLimit, executionMaxPerTx, owner);
|
||||
})
|
||||
it('calls contractFallback', async () => {
|
||||
const receiver = await ERC677ReceiverTest.new();
|
||||
|
@ -260,7 +420,7 @@ contract('ERC677BridgeToken', async (accounts) => {
|
|||
it('can take send ERC20 tokens', async ()=> {
|
||||
const owner = accounts[0];
|
||||
const halfEther = web3.toBigNumber(web3.toWei(0.5, "ether"));
|
||||
let tokenSecond = await POA20.new("Roman Token", "RST", 18);
|
||||
let tokenSecond = await tokenContract.new("Roman Token", "RST", 18);
|
||||
|
||||
await tokenSecond.mint(accounts[0], halfEther).should.be.fulfilled;
|
||||
halfEther.should.be.bignumber.equal(await tokenSecond.balanceOf(accounts[0]))
|
||||
|
@ -271,7 +431,6 @@ contract('ERC677BridgeToken', async (accounts) => {
|
|||
await token.claimTokens(tokenSecond.address, accounts[3], {from: owner});
|
||||
'0'.should.be.bignumber.equal(await tokenSecond.balanceOf(token.address))
|
||||
halfEther.should.be.bignumber.equal(await tokenSecond.balanceOf(accounts[3]))
|
||||
|
||||
})
|
||||
})
|
||||
describe('#transfer', async () => {
|
||||
|
@ -293,7 +452,7 @@ contract('ERC677BridgeToken', async (accounts) => {
|
|||
logs[0].event.should.be.equal("Transfer")
|
||||
})
|
||||
it('if transfer called on contract, still works even if onTokenTransfer doesnot exist', async () => {
|
||||
const someContract = await POA20.new("Some", "Token", 18);
|
||||
const someContract = await tokenContract.new("Some", "Token", 18);
|
||||
await token.mint(user, 2, {from: owner }).should.be.fulfilled;
|
||||
const tokenTransfer = await token.transfer(someContract.address, 1, {from: user}).should.be.fulfilled;
|
||||
const tokenTransfer2 = await token.transfer(accounts[0], 1, {from: user}).should.be.fulfilled;
|
||||
|
@ -301,7 +460,14 @@ contract('ERC677BridgeToken', async (accounts) => {
|
|||
(await token.balanceOf(user)).should.be.bignumber.equal(0);
|
||||
tokenTransfer.logs[0].event.should.be.equal("Transfer")
|
||||
tokenTransfer2.logs[0].event.should.be.equal("Transfer")
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
contract('ERC677BridgeToken', async (accounts) => {
|
||||
await testERC677BridgeToken(accounts, false);
|
||||
})
|
||||
|
||||
contract('ERC677BridgeTokenRewardable', async (accounts) => {
|
||||
await testERC677BridgeToken(accounts, true);
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue