Support negative decimal shift (#448)

This commit is contained in:
Kirill Fedoseev 2020-07-18 03:16:41 +07:00 committed by GitHub
parent 1ed52725fc
commit f8aea2366c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 1098 additions and 887 deletions

View File

@ -23,6 +23,7 @@
"no-use-before-define": ["error", { "functions": false }],
"no-restricted-syntax": "off",
"node/no-unpublished-require": "off",
"func-names": "off"
"func-names": "off",
"no-loop-func": "off"
}
}

View File

@ -2,9 +2,10 @@ pragma solidity 0.4.24;
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "../upgradeability/EternalStorage.sol";
import "./DecimalShiftBridge.sol";
import "./Ownable.sol";
contract BasicTokenBridge is EternalStorage, Ownable {
contract BasicTokenBridge is EternalStorage, Ownable, DecimalShiftBridge {
using SafeMath for uint256;
event DailyLimitChanged(uint256 newLimit);
@ -15,7 +16,6 @@ contract BasicTokenBridge is EternalStorage, Ownable {
bytes32 internal constant DAILY_LIMIT = 0x4a6a899679f26b73530d8cf1001e83b6f7702e04b6fdb98f3c62dc7e47e041a5; // keccak256(abi.encodePacked("dailyLimit"))
bytes32 internal constant EXECUTION_MAX_PER_TX = 0xc0ed44c192c86d1cc1ba51340b032c2766b4a2b0041031de13c46dd7104888d5; // keccak256(abi.encodePacked("executionMaxPerTx"))
bytes32 internal constant EXECUTION_DAILY_LIMIT = 0x21dbcab260e413c20dc13c28b7db95e2b423d1135f42bb8b7d5214a92270d237; // keccak256(abi.encodePacked("executionDailyLimit"))
bytes32 internal constant DECIMAL_SHIFT = 0x1e8ecaafaddea96ed9ac6d2642dcdfe1bebe58a930b1085842d8fc122b371ee5; // keccak256(abi.encodePacked("decimalShift"))
function totalSpentPerDay(uint256 _day) public view returns (uint256) {
return uintStorage[keccak256(abi.encodePacked("totalSpentPerDay", _day))];
@ -45,10 +45,6 @@ contract BasicTokenBridge is EternalStorage, Ownable {
return uintStorage[MIN_PER_TX];
}
function decimalShift() public view returns (uint256) {
return uintStorage[DECIMAL_SHIFT];
}
function withinLimit(uint256 _amount) public view returns (bool) {
uint256 nextLimit = totalSpentPerDay(getCurrentDay()).add(_amount);
return dailyLimit() >= nextLimit && _amount <= maxPerTx() && _amount >= minPerTx();

View File

@ -0,0 +1,64 @@
pragma solidity 0.4.24;
import "../upgradeability/EternalStorage.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
contract DecimalShiftBridge is EternalStorage {
using SafeMath for uint256;
bytes32 internal constant DECIMAL_SHIFT = 0x1e8ecaafaddea96ed9ac6d2642dcdfe1bebe58a930b1085842d8fc122b371ee5; // keccak256(abi.encodePacked("decimalShift"))
/**
* @dev Internal function for setting the decimal shift for bridge operations.
* Decimal shift can be positive, negative, or equal to zero.
* It has the following meaning: N tokens in the foreign chain are equivalent to N * pow(10, shift) tokens on the home side.
* @param _shift new value of decimal shift.
*/
function _setDecimalShift(int256 _shift) internal {
// since 1 wei * 10**77 > 2**255, it does not make any sense to use higher values
require(_shift > -77 && _shift < 77);
uintStorage[DECIMAL_SHIFT] = uint256(_shift);
}
/**
* @dev Returns the value of foreign-to-home decimal shift.
* @return decimal shift.
*/
function decimalShift() public view returns (int256) {
return int256(uintStorage[DECIMAL_SHIFT]);
}
/**
* @dev Converts the amount of home tokens into the equivalent amount of foreign tokens.
* @param _value amount of home tokens.
* @return equivalent amount of foreign tokens.
*/
function _unshiftValue(uint256 _value) internal view returns (uint256) {
return _shiftUint(_value, -decimalShift());
}
/**
* @dev Converts the amount of foreign tokens into the equivalent amount of home tokens.
* @param _value amount of foreign tokens.
* @return equivalent amount of home tokens.
*/
function _shiftValue(uint256 _value) internal view returns (uint256) {
return _shiftUint(_value, decimalShift());
}
/**
* @dev Calculates _value * pow(10, _shift).
* @param _value amount of tokens.
* @param _shift decimal shift to apply.
* @return shifted value.
*/
function _shiftUint(uint256 _value, int256 _shift) private pure returns (uint256) {
if (_shift == 0) {
return _value;
}
if (_shift > 0) {
return _value.mul(10**uint256(_shift));
}
return _value.div(10**uint256(-_shift));
}
}

View File

@ -29,7 +29,7 @@ contract BasicAMBErc20ToNative is Initializable, Upgradeable, Claimable, Version
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = dailyLimit, 1 = maxPerTx, 2 = minPerTx ]
uint256[2] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = executionDailyLimit, 1 = executionMaxPerTx ]
uint256 _requestGasLimit,
uint256 _decimalShift,
int256 _decimalShift,
address _owner
) internal {
require(!isInitialized());
@ -49,7 +49,7 @@ contract BasicAMBErc20ToNative is Initializable, Upgradeable, Claimable, Version
uintStorage[MIN_PER_TX] = _dailyLimitMaxPerTxMinPerTxArray[2];
uintStorage[EXECUTION_DAILY_LIMIT] = _executionDailyLimitExecutionMaxPerTxArray[0];
uintStorage[EXECUTION_MAX_PER_TX] = _executionDailyLimitExecutionMaxPerTxArray[1];
uintStorage[DECIMAL_SHIFT] = _decimalShift;
_setDecimalShift(_decimalShift);
setOwner(_owner);
emit DailyLimitChanged(_dailyLimitMaxPerTxMinPerTxArray[0]);

View File

@ -31,7 +31,7 @@ contract ForeignAMBErc20ToNative is BasicAMBErc20ToNative, ReentrancyGuard, Base
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = dailyLimit, 1 = maxPerTx, 2 = minPerTx ]
uint256[2] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = executionDailyLimit, 1 = executionMaxPerTx ]
uint256 _requestGasLimit,
uint256 _decimalShift,
int256 _decimalShift,
address _owner,
address _erc677token
) external onlyRelevantSender returns (bool) {
@ -139,7 +139,7 @@ contract ForeignAMBErc20ToNative is BasicAMBErc20ToNative, ReentrancyGuard, Base
* @param _value amount of tokens to be received
*/
function executeActionOnBridgedTokens(address _receiver, uint256 _value) internal {
uint256 valueToTransfer = _value.div(10**decimalShift());
uint256 valueToTransfer = _unshiftValue(_value);
bytes32 _messageId = messageId();
_setMediatorBalance(mediatorBalance().sub(valueToTransfer));

View File

@ -31,7 +31,7 @@ contract HomeAMBErc20ToNative is BasicAMBErc20ToNative, BlockRewardBridge, HomeF
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = dailyLimit, 1 = maxPerTx, 2 = minPerTx ]
uint256[2] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = executionDailyLimit, 1 = executionMaxPerTx ]
uint256 _requestGasLimit,
uint256 _decimalShift,
int256 _decimalShift,
address _owner,
address _blockReward
) public onlyRelevantSender returns (bool) {
@ -71,7 +71,7 @@ contract HomeAMBErc20ToNative is BasicAMBErc20ToNative, BlockRewardBridge, HomeF
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = dailyLimit, 1 = maxPerTx, 2 = minPerTx ]
uint256[2] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = executionDailyLimit, 1 = executionMaxPerTx ]
uint256 _requestGasLimit,
uint256 _decimalShift,
int256 _decimalShift,
address _owner,
address _blockReward,
address[] _rewardAddreses,
@ -177,7 +177,7 @@ contract HomeAMBErc20ToNative is BasicAMBErc20ToNative, BlockRewardBridge, HomeF
* @param _value amount of native tokens to be received
*/
function executeActionOnBridgedTokens(address _receiver, uint256 _value) internal {
uint256 valueToMint = _value.mul(10**decimalShift());
uint256 valueToMint = _shiftValue(_value);
bytes32 _messageId = messageId();
uint256 fee = _distributeFee(FOREIGN_TO_HOME_FEE, valueToMint);

View File

@ -32,7 +32,7 @@ contract BasicAMBErc677ToErc677 is
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = _dailyLimit, 1 = _maxPerTx, 2 = _minPerTx ]
uint256[2] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = _executionDailyLimit, 1 = _executionMaxPerTx ]
uint256 _requestGasLimit,
uint256 _decimalShift,
int256 _decimalShift,
address _owner
) public onlyRelevantSender returns (bool) {
require(!isInitialized());
@ -52,7 +52,7 @@ contract BasicAMBErc677ToErc677 is
uintStorage[EXECUTION_DAILY_LIMIT] = _executionDailyLimitExecutionMaxPerTxArray[0];
uintStorage[EXECUTION_MAX_PER_TX] = _executionDailyLimitExecutionMaxPerTxArray[1];
_setRequestGasLimit(_requestGasLimit);
uintStorage[DECIMAL_SHIFT] = _decimalShift;
_setDecimalShift(_decimalShift);
setOwner(_owner);
setInitialize();

View File

@ -14,7 +14,7 @@ contract ForeignAMBErc677ToErc677 is BasicAMBErc677ToErc677 {
* @param _value amount of bridged tokens
*/
function executeActionOnBridgedTokens(address _recipient, uint256 _value) internal {
uint256 value = _value.div(10**decimalShift());
uint256 value = _unshiftValue(_value);
bytes32 _messageId = messageId();
erc677token().transfer(_recipient, value);
emit TokensBridged(_recipient, value, _messageId);

View File

@ -15,7 +15,7 @@ contract ForeignStakeTokenMediator is BasicStakeTokenMediator {
* @param _value amount of bridged tokens
*/
function executeActionOnBridgedTokens(address _recipient, uint256 _value) internal {
uint256 value = _value.div(10**decimalShift());
uint256 value = _unshiftValue(_value);
bytes32 _messageId = messageId();
_transferWithOptionalMint(_recipient, value);
emit TokensBridged(_recipient, value, _messageId);

View File

@ -15,7 +15,7 @@ contract HomeAMBErc677ToErc677 is BasicAMBErc677ToErc677 {
* @param _value amount of bridged tokens
*/
function executeActionOnBridgedTokens(address _recipient, uint256 _value) internal {
uint256 value = _value.mul(10**decimalShift());
uint256 value = _shiftValue(_value);
bytes32 _messageId = messageId();
IBurnableMintableERC677Token(erc677token()).mint(_recipient, value);
emit TokensBridged(_recipient, value, _messageId);

View File

@ -21,7 +21,7 @@ contract HomeStakeTokenMediator is BasicStakeTokenMediator, HomeStakeTokenFeeMan
* @param _dailyLimitMaxPerTxMinPerTxArray Home limits for outgoing transfers
* @param _executionDailyLimitExecutionMaxPerTxArray Home execution limits for incoming transfers
* @param _requestGasLimit gas limit used for AMB operations
* @param _decimalShift decimal shift for bridged TAKE token
* @param _decimalShift decimal shift for bridged STAKE token
* @param _owner address of new bridge owner
*/
function initialize(
@ -31,7 +31,7 @@ contract HomeStakeTokenMediator is BasicStakeTokenMediator, HomeStakeTokenFeeMan
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = _dailyLimit, 1 = _maxPerTx, 2 = _minPerTx ]
uint256[2] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = _executionDailyLimit, 1 = _executionMaxPerTx ]
uint256 _requestGasLimit,
uint256 _decimalShift,
int256 _decimalShift,
address _owner
) public returns (bool) {
addressStorage[MINT_HANDLER] = _erc677token;
@ -56,7 +56,7 @@ contract HomeStakeTokenMediator is BasicStakeTokenMediator, HomeStakeTokenFeeMan
* @param _dailyLimitMaxPerTxMinPerTxArray Home limits for outgoing transfers
* @param _executionDailyLimitExecutionMaxPerTxArray Home execution limits for incoming transfers
* @param _requestGasLimit gas limit used for AMB operations
* @param _decimalShift decimal shift for bridged TAKE token
* @param _decimalShift decimal shift for bridged STAKE token
* @param _owner address of new bridge owner
* @param _blockReward address of block reward contract used for fee distribution
* @param _fee initial home fee
@ -68,7 +68,7 @@ contract HomeStakeTokenMediator is BasicStakeTokenMediator, HomeStakeTokenFeeMan
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = _dailyLimit, 1 = _maxPerTx, 2 = _minPerTx ]
uint256[2] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = _executionDailyLimit, 1 = _executionMaxPerTx ]
uint256 _requestGasLimit,
uint256 _decimalShift,
int256 _decimalShift,
address _owner,
address _blockReward,
uint256 _fee
@ -122,7 +122,7 @@ contract HomeStakeTokenMediator is BasicStakeTokenMediator, HomeStakeTokenFeeMan
* @param _value amount of bridged tokens
*/
function executeActionOnBridgedTokens(address _recipient, uint256 _value) internal {
uint256 value = _value.mul(10**decimalShift());
uint256 value = _shiftValue(_value);
bytes32 _messageId = messageId();
getMintHandler().mint(_recipient, value);
emit TokensBridged(_recipient, value, _messageId);

View File

@ -38,7 +38,7 @@ contract BasicAMBNativeToErc20 is
uint256[3] _dailyLimitMaxPerTxMinPerTxArray,
uint256[2] _executionDailyLimitExecutionMaxPerTxArray,
uint256 _requestGasLimit,
uint256 _decimalShift,
int256 _decimalShift,
address _owner,
address _feeManager
) internal {
@ -59,7 +59,7 @@ contract BasicAMBNativeToErc20 is
uintStorage[MIN_PER_TX] = _dailyLimitMaxPerTxMinPerTxArray[2];
uintStorage[EXECUTION_DAILY_LIMIT] = _executionDailyLimitExecutionMaxPerTxArray[0];
uintStorage[EXECUTION_MAX_PER_TX] = _executionDailyLimitExecutionMaxPerTxArray[1];
uintStorage[DECIMAL_SHIFT] = _decimalShift;
_setDecimalShift(_decimalShift);
_setFeeManagerContract(_feeManager);
setOwner(_owner);

View File

@ -32,7 +32,7 @@ contract ForeignAMBNativeToErc20 is BasicAMBNativeToErc20, ReentrancyGuard, Base
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = dailyLimit, 1 = maxPerTx, 2 = minPerTx ]
uint256[2] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = executionDailyLimit, 1 = executionMaxPerTx ]
uint256 _requestGasLimit,
uint256 _decimalShift,
int256 _decimalShift,
address _owner,
address _erc677token,
address _feeManager
@ -67,7 +67,7 @@ contract ForeignAMBNativeToErc20 is BasicAMBNativeToErc20, ReentrancyGuard, Base
* @param _value amount of tokens to be received
*/
function executeActionOnBridgedTokens(address _receiver, uint256 _value) internal {
uint256 valueToMint = _value.div(10**decimalShift());
uint256 valueToMint = _unshiftValue(_value);
bytes32 _messageId = messageId();
IMediatorFeeManager feeManager = feeManagerContract();

View File

@ -29,7 +29,7 @@ contract HomeAMBNativeToErc20 is BasicAMBNativeToErc20 {
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = dailyLimit, 1 = maxPerTx, 2 = minPerTx ]
uint256[2] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = executionDailyLimit, 1 = executionMaxPerTx ]
uint256 _requestGasLimit,
uint256 _decimalShift,
int256 _decimalShift,
address _owner,
address _feeManager
) external onlyRelevantSender returns (bool) {
@ -84,7 +84,7 @@ contract HomeAMBNativeToErc20 is BasicAMBNativeToErc20 {
* @param _value amount of native tokens to be received
*/
function executeActionOnBridgedTokens(address _receiver, uint256 _value) internal {
uint256 valueToTransfer = _value.mul(10**decimalShift());
uint256 valueToTransfer = _shiftValue(_value);
setMediatorBalance(mediatorBalance().sub(valueToTransfer));
bytes32 _messageId = messageId();

View File

@ -12,7 +12,7 @@ contract BasicForeignBridgeErcToErc is BasicForeignBridge {
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = _dailyLimit, 1 = _maxPerTx, 2 = _minPerTx ]
uint256[2] _homeDailyLimitHomeMaxPerTxArray, // [ 0 = _homeDailyLimit, 1 = _homeMaxPerTx ]
address _owner,
uint256 _decimalShift
int256 _decimalShift
) internal {
require(!isInitialized());
require(AddressUtils.isContract(_validatorContract));
@ -35,7 +35,7 @@ contract BasicForeignBridgeErcToErc is BasicForeignBridge {
uintStorage[MIN_PER_TX] = _dailyLimitMaxPerTxMinPerTxArray[2];
uintStorage[EXECUTION_DAILY_LIMIT] = _homeDailyLimitHomeMaxPerTxArray[0];
uintStorage[EXECUTION_MAX_PER_TX] = _homeDailyLimitHomeMaxPerTxArray[1];
uintStorage[DECIMAL_SHIFT] = _decimalShift;
_setDecimalShift(_decimalShift);
setOwner(_owner);
setInitialize();
@ -59,7 +59,7 @@ contract BasicForeignBridgeErcToErc is BasicForeignBridge {
bytes32 /*_txHash*/
) internal returns (bool) {
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount));
uint256 amount = _amount.div(10**decimalShift());
uint256 amount = _unshiftValue(_amount);
return erc20token().transfer(_recipient, amount);
}

View File

@ -12,7 +12,7 @@ contract ForeignBridgeErc677ToErc677 is ERC677Bridge, BasicForeignBridgeErcToErc
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = _dailyLimit, 1 = _maxPerTx, 2 = _minPerTx ]
uint256[2] _homeDailyLimitHomeMaxPerTxArray, // [ 0 = _homeDailyLimit, 1 = _homeMaxPerTx ]
address _owner,
uint256 _decimalShift
int256 _decimalShift
) external onlyRelevantSender returns (bool) {
_initialize(
_validatorContract,

View File

@ -12,7 +12,7 @@ contract ForeignBridgeErcToErc is BasicForeignBridgeErcToErc, ERC20Bridge {
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = _dailyLimit, 1 = _maxPerTx, 2 = _minPerTx ]
uint256[2] _homeDailyLimitHomeMaxPerTxArray, // [ 0 = _homeDailyLimit, 1 = _homeMaxPerTx ]
address _owner,
uint256 _decimalShift
int256 _decimalShift
) external onlyRelevantSender returns (bool) {
_initialize(
_validatorContract,

View File

@ -23,7 +23,7 @@ contract HomeBridgeErcToErc is
address _erc677token,
uint256[2] _foreignDailyLimitForeignMaxPerTxArray, // [ 0 = _foreignDailyLimit, 1 = _foreignMaxPerTx ]
address _owner,
uint256 _decimalShift
int256 _decimalShift
) external onlyRelevantSender returns (bool) {
_initialize(
_validatorContract,
@ -50,7 +50,7 @@ contract HomeBridgeErcToErc is
address _owner,
address _feeManager,
uint256[2] _homeFeeForeignFeeArray, // [ 0 = _homeFee, 1 = _foreignFee ]
uint256 _decimalShift
int256 _decimalShift
) external onlyRelevantSender returns (bool) {
_rewardableInitialize(
_validatorContract,
@ -79,7 +79,7 @@ contract HomeBridgeErcToErc is
address _owner,
address _feeManager,
uint256[2] _homeFeeForeignFeeArray, // [ 0 = _homeFee, 1 = _foreignFee ]
uint256 _decimalShift
int256 _decimalShift
) internal {
_initialize(
_validatorContract,
@ -105,7 +105,7 @@ contract HomeBridgeErcToErc is
address _erc677token,
uint256[2] _foreignDailyLimitForeignMaxPerTxArray, // [ 0 = _foreignDailyLimit, 1 = _foreignMaxPerTx ]
address _owner,
uint256 _decimalShift
int256 _decimalShift
) internal {
require(!isInitialized());
require(AddressUtils.isContract(_validatorContract));
@ -126,7 +126,7 @@ contract HomeBridgeErcToErc is
uintStorage[REQUIRED_BLOCK_CONFIRMATIONS] = _requiredBlockConfirmations;
uintStorage[EXECUTION_DAILY_LIMIT] = _foreignDailyLimitForeignMaxPerTxArray[0];
uintStorage[EXECUTION_MAX_PER_TX] = _foreignDailyLimitForeignMaxPerTxArray[1];
uintStorage[DECIMAL_SHIFT] = _decimalShift;
_setDecimalShift(_decimalShift);
setOwner(_owner);
setErc677token(_erc677token);
@ -145,7 +145,7 @@ contract HomeBridgeErcToErc is
function onExecuteAffirmation(address _recipient, uint256 _value, bytes32 txHash) internal returns (bool) {
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_value));
uint256 valueToMint = _value.mul(10**decimalShift());
uint256 valueToMint = _shiftValue(_value);
address feeManager = feeManagerContract();
if (feeManager != address(0)) {
uint256 fee = calculateFee(valueToMint, false, feeManager, FOREIGN_FEE);

View File

@ -17,7 +17,7 @@ contract HomeBridgeErcToErcPOSDAO is HomeBridgeErcToErc {
address _feeManager,
uint256[2] _homeFeeForeignFeeArray, // [ 0 = _homeFee, 1 = _foreignFee ]
address _blockReward,
uint256 _decimalShift
int256 _decimalShift
) external onlyRelevantSender returns (bool) {
_rewardableInitialize(
_validatorContract,

View File

@ -19,7 +19,7 @@ contract ForeignBridgeErcToNative is BasicForeignBridge, ERC20Bridge, OtherSideB
uint256[3] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = _dailyLimit, 1 = _maxPerTx, 2 = _minPerTx ]
uint256[2] _homeDailyLimitHomeMaxPerTxArray, //[ 0 = _homeDailyLimit, 1 = _homeMaxPerTx ]
address _owner,
uint256 _decimalShift,
int256 _decimalShift,
address _bridgeOnOtherSide
) external onlyRelevantSender returns (bool) {
require(!isInitialized());
@ -44,7 +44,7 @@ contract ForeignBridgeErcToNative is BasicForeignBridge, ERC20Bridge, OtherSideB
uintStorage[MIN_PER_TX] = _dailyLimitMaxPerTxMinPerTxArray[2];
uintStorage[EXECUTION_DAILY_LIMIT] = _homeDailyLimitHomeMaxPerTxArray[0];
uintStorage[EXECUTION_MAX_PER_TX] = _homeDailyLimitHomeMaxPerTxArray[1];
uintStorage[DECIMAL_SHIFT] = _decimalShift;
_setDecimalShift(_decimalShift);
setOwner(_owner);
_setBridgeContractOnOtherSide(_bridgeOnOtherSide);
setInitialize();
@ -86,7 +86,7 @@ contract ForeignBridgeErcToNative is BasicForeignBridge, ERC20Bridge, OtherSideB
bytes32 /*_txHash*/
) internal returns (bool) {
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount));
uint256 amount = _amount.div(10**decimalShift());
uint256 amount = _unshiftValue(_amount);
uint256 currentBalance = tokenBalance(erc20token());

View File

@ -55,7 +55,7 @@ contract HomeBridgeErcToNative is
address _blockReward,
uint256[2] _foreignDailyLimitForeignMaxPerTxArray, // [ 0 = _foreignDailyLimit, 1 = _foreignMaxPerTx ]
address _owner,
uint256 _decimalShift
int256 _decimalShift
) external onlyRelevantSender returns (bool) {
_initialize(
_validatorContract,
@ -82,7 +82,7 @@ contract HomeBridgeErcToNative is
address _owner,
address _feeManager,
uint256[2] _homeFeeForeignFeeArray, // [ 0 = _homeFee, 1 = _foreignFee ]
uint256 _decimalShift
int256 _decimalShift
) external onlyRelevantSender returns (bool) {
_initialize(
_validatorContract,
@ -127,7 +127,7 @@ contract HomeBridgeErcToNative is
address _blockReward,
uint256[2] _foreignDailyLimitForeignMaxPerTxArray, // [ 0 = _foreignDailyLimit, 1 = _foreignMaxPerTx ]
address _owner,
uint256 _decimalShift
int256 _decimalShift
) internal {
require(!isInitialized());
require(AddressUtils.isContract(_validatorContract));
@ -151,7 +151,7 @@ contract HomeBridgeErcToNative is
addressStorage[BLOCK_REWARD_CONTRACT] = _blockReward;
uintStorage[EXECUTION_DAILY_LIMIT] = _foreignDailyLimitForeignMaxPerTxArray[0];
uintStorage[EXECUTION_MAX_PER_TX] = _foreignDailyLimitForeignMaxPerTxArray[1];
uintStorage[DECIMAL_SHIFT] = _decimalShift;
_setDecimalShift(_decimalShift);
setOwner(_owner);
emit RequiredBlockConfirmationChanged(_requiredBlockConfirmations);
@ -163,7 +163,7 @@ contract HomeBridgeErcToNative is
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_value));
IBlockReward blockReward = blockRewardContract();
require(blockReward != address(0));
uint256 valueToMint = _value.mul(10**decimalShift());
uint256 valueToMint = _shiftValue(_value);
address feeManager = feeManagerContract();
if (feeManager != address(0)) {
uint256 fee = calculateFee(valueToMint, false, feeManager, FOREIGN_FEE);

View File

@ -10,7 +10,7 @@ contract ClassicHomeBridgeNativeToErc is HomeBridgeNativeToErc {
uint256 _requiredBlockConfirmations,
uint256[2] _foreignDailyLimitForeignMaxPerTxArray, // [ 0 = _foreignDailyLimit, 1 = _foreignMaxPerTx ]
address _owner,
uint256 _decimalShift
int256 _decimalShift
) internal {
super._initialize(
_validatorContract,

View File

@ -19,7 +19,7 @@ contract ForeignBridgeNativeToErc is
uint256 _requiredBlockConfirmations,
uint256[2] _homeDailyLimitHomeMaxPerTxArray, // [ 0 = _homeDailyLimit, 1 = _homeMaxPerTx ]
address _owner,
uint256 _decimalShift,
int256 _decimalShift,
address _bridgeOnOtherSide
) external onlyRelevantSender returns (bool) {
_initialize(
@ -47,7 +47,7 @@ contract ForeignBridgeNativeToErc is
address _owner,
address _feeManager,
uint256 _homeFee,
uint256 _decimalShift,
int256 _decimalShift,
address _bridgeOnOtherSide
) external onlyRelevantSender returns (bool) {
_initialize(
@ -84,7 +84,7 @@ contract ForeignBridgeNativeToErc is
uint256 _requiredBlockConfirmations,
uint256[2] _homeDailyLimitHomeMaxPerTxArray, // [ 0 = _homeDailyLimit, 1 = _homeMaxPerTx ]
address _owner,
uint256 _decimalShift,
int256 _decimalShift,
address _bridgeOnOtherSide
) internal {
require(!isInitialized());
@ -108,7 +108,7 @@ contract ForeignBridgeNativeToErc is
uintStorage[REQUIRED_BLOCK_CONFIRMATIONS] = _requiredBlockConfirmations;
uintStorage[EXECUTION_DAILY_LIMIT] = _homeDailyLimitHomeMaxPerTxArray[0];
uintStorage[EXECUTION_MAX_PER_TX] = _homeDailyLimitHomeMaxPerTxArray[1];
uintStorage[DECIMAL_SHIFT] = _decimalShift;
_setDecimalShift(_decimalShift);
setOwner(_owner);
_setBridgeContractOnOtherSide(_bridgeOnOtherSide);
@ -119,7 +119,7 @@ contract ForeignBridgeNativeToErc is
function onExecuteMessage(address _recipient, uint256 _amount, bytes32 _txHash) internal returns (bool) {
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount));
uint256 valueToMint = _amount.div(10**decimalShift());
uint256 valueToMint = _unshiftValue(_amount);
address feeManager = feeManagerContract();
if (feeManager != address(0)) {
uint256 fee = calculateFee(valueToMint, false, feeManager, HOME_FEE);

View File

@ -36,7 +36,7 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicHomeBridge, RewardableHom
uint256 _requiredBlockConfirmations,
uint256[2] _foreignDailyLimitForeignMaxPerTxArray, // [ 0 = _foreignDailyLimit, 1 = _foreignMaxPerTx ]
address _owner,
uint256 _decimalShift
int256 _decimalShift
) external onlyRelevantSender returns (bool) {
_initialize(
_validatorContract,
@ -60,7 +60,7 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicHomeBridge, RewardableHom
address _owner,
address _feeManager,
uint256[2] _homeFeeForeignFeeArray, // [ 0 = _homeFee, 1 = _foreignFee ]
uint256 _decimalShift
int256 _decimalShift
) external onlyRelevantSender returns (bool) {
_initialize(
_validatorContract,
@ -90,7 +90,7 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicHomeBridge, RewardableHom
uint256 _requiredBlockConfirmations,
uint256[2] _foreignDailyLimitForeignMaxPerTxArray, // [ 0 = _foreignDailyLimit, 1 = _foreignMaxPerTx ]
address _owner,
uint256 _decimalShift
int256 _decimalShift
) internal {
require(!isInitialized());
require(AddressUtils.isContract(_validatorContract));
@ -112,7 +112,7 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicHomeBridge, RewardableHom
uintStorage[REQUIRED_BLOCK_CONFIRMATIONS] = _requiredBlockConfirmations;
uintStorage[EXECUTION_DAILY_LIMIT] = _foreignDailyLimitForeignMaxPerTxArray[0];
uintStorage[EXECUTION_MAX_PER_TX] = _foreignDailyLimitForeignMaxPerTxArray[1];
uintStorage[DECIMAL_SHIFT] = _decimalShift;
_setDecimalShift(_decimalShift);
setOwner(_owner);
emit RequiredBlockConfirmationChanged(_requiredBlockConfirmations);
@ -137,7 +137,7 @@ contract HomeBridgeNativeToErc is EternalStorage, BasicHomeBridge, RewardableHom
function onExecuteAffirmation(address _recipient, uint256 _value, bytes32 txHash) internal returns (bool) {
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_value));
uint256 valueToTransfer = _value.mul(10**decimalShift());
uint256 valueToTransfer = _shiftValue(_value);
address feeManager = feeManagerContract();
if (feeManager != address(0)) {

View File

@ -142,6 +142,18 @@ contract('ForeignAMBErc20ToNative', async accounts => {
token.address
).should.be.rejected
// not valid decimal shift
await contract.initialize(
ambBridgeContract.address,
otherSideMediator.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
100,
owner,
token.address
).should.be.rejected
const { logs } = await contract.initialize(
ambBridgeContract.address,
otherSideMediator.address,
@ -453,79 +465,80 @@ contract('ForeignAMBErc20ToNative', async accounts => {
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
it('should unlock tokens on message from amb with decimal shift of two', async () => {
// Given
const decimalShiftTwo = 2
for (const decimalShift of [2, -1]) {
it(`should unlock tokens on message from amb with decimal shift of ${decimalShift}`, async () => {
// Given
contract = await ForeignAMBErc20ToNative.new()
await contract.initialize(
ambBridgeContract.address,
otherSideMediator.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShiftTwo,
owner,
token.address
).should.be.fulfilled
await token.transfer(contract.address, value, { from: user }).should.be.fulfilled
await token.transfer(contract.address, value, { from: user }).should.be.fulfilled
expect(await token.balanceOf(contract.address)).to.be.bignumber.equal(twoEthers)
expect(await contract.mediatorBalance()).to.be.bignumber.equal(twoEthers)
contract = await ForeignAMBErc20ToNative.new()
await contract.initialize(
ambBridgeContract.address,
otherSideMediator.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShift,
owner,
token.address
).should.be.fulfilled
await token.transfer(contract.address, value, { from: user }).should.be.fulfilled
await token.transfer(contract.address, value, { from: user }).should.be.fulfilled
expect(await token.balanceOf(contract.address)).to.be.bignumber.equal(twoEthers)
expect(await contract.mediatorBalance()).to.be.bignumber.equal(twoEthers)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const data = await contract.contract.methods.handleBridgedTokens(user, valueOnHome.toString()).encodeABI()
const data = await contract.contract.methods.handleBridgedTokens(user, valueOnHome.toString()).encodeABI()
await ambBridgeContract.executeMessageCall(
contract.address,
otherSideMediator.address,
data,
exampleMessageId,
1000000
).should.be.fulfilled
await ambBridgeContract.executeMessageCall(
contract.address,
otherSideMediator.address,
data,
exampleMessageId,
1000000
).should.be.fulfilled
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
// Then
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnHome)
expect(await token.balanceOf(user)).to.be.bignumber.equal(valueOnForeign)
expect(await contract.mediatorBalance()).to.be.bignumber.equal(twoEthers.sub(valueOnForeign))
// Then
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnHome)
expect(await token.balanceOf(user)).to.be.bignumber.equal(valueOnForeign)
expect(await contract.mediatorBalance()).to.be.bignumber.equal(twoEthers.sub(valueOnForeign))
const event = await getEvents(contract, { event: 'TokensBridged' })
expect(event.length).to.be.equal(1)
expect(event[0].returnValues.recipient).to.be.equal(user)
expect(event[0].returnValues.value).to.be.equal(valueOnForeign.toString())
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
const event = await getEvents(contract, { event: 'TokensBridged' })
expect(event.length).to.be.equal(1)
expect(event[0].returnValues.recipient).to.be.equal(user)
expect(event[0].returnValues.value).to.be.equal(valueOnForeign.toString())
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
it('should revert when out of execution limits on message from amb', async () => {
await token.transfer(contract.address, value, { from: user }).should.be.fulfilled
await token.transfer(contract.address, value, { from: user }).should.be.fulfilled
expect(await token.balanceOf(contract.address)).to.be.bignumber.equal(twoEthers)
expect(await contract.mediatorBalance()).to.be.bignumber.equal(twoEthers)
it('should revert when out of execution limits on message from amb', async () => {
await token.transfer(contract.address, value, { from: user }).should.be.fulfilled
await token.transfer(contract.address, value, { from: user }).should.be.fulfilled
expect(await token.balanceOf(contract.address)).to.be.bignumber.equal(twoEthers)
expect(await contract.mediatorBalance()).to.be.bignumber.equal(twoEthers)
// Given
const outOfLimitValueData = await contract.contract.methods
.handleBridgedTokens(user, twoEthers.toString())
.encodeABI()
// Given
const outOfLimitValueData = await contract.contract.methods
.handleBridgedTokens(user, twoEthers.toString())
.encodeABI()
// when
await ambBridgeContract.executeMessageCall(
contract.address,
otherSideMediator.address,
outOfLimitValueData,
failedMessageId,
1000000
).should.be.fulfilled
// when
await ambBridgeContract.executeMessageCall(
contract.address,
otherSideMediator.address,
outOfLimitValueData,
failedMessageId,
1000000
).should.be.fulfilled
expect(await ambBridgeContract.messageCallStatus(failedMessageId)).to.be.equal(false)
expect(await ambBridgeContract.messageCallStatus(failedMessageId)).to.be.equal(false)
// Then
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(ZERO)
expect(await token.balanceOf(user)).to.be.bignumber.equal(ZERO)
})
// Then
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(ZERO)
expect(await token.balanceOf(user)).to.be.bignumber.equal(ZERO)
})
}
})
describe('requestFailedMessageFix', () => {

View File

@ -153,6 +153,18 @@ contract('HomeAMBErc20ToNative', async accounts => {
blockReward.address
).should.be.rejected
// not valid decimal shift
await contract.initialize(
ambBridgeContract.address,
otherSideMediator.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
100,
owner,
blockReward.address
).should.be.rejected
const { logs } = await contract.initialize(
ambBridgeContract.address,
otherSideMediator.address,
@ -748,47 +760,47 @@ contract('HomeAMBErc20ToNative', async accounts => {
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
it('should unlock tokens on message from amb with decimal shift of two', async () => {
// Given
const decimalShiftTwo = 2
for (const decimalShift of [2, -1]) {
it(`should unlock tokens on message from amb with decimal shift of ${decimalShift}`, async () => {
// Given
contract = await HomeAMBErc20ToNative.new()
await contract.initialize(
ambBridgeContract.address,
otherSideMediator.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShift,
owner,
blockReward.address
).should.be.fulfilled
await blockReward.setBridgeContractAddress(contract.address)
contract = await HomeAMBErc20ToNative.new()
await contract.initialize(
ambBridgeContract.address,
otherSideMediator.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShiftTwo,
owner,
blockReward.address
).should.be.fulfilled
await blockReward.setBridgeContractAddress(contract.address)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const data = await contract.contract.methods.handleBridgedTokens(user, valueOnForeign.toString()).encodeABI()
const data = await contract.contract.methods.handleBridgedTokens(user, valueOnForeign.toString()).encodeABI()
await ambBridgeContract.executeMessageCall(
contract.address,
otherSideMediator.address,
data,
exampleMessageId,
1000000
).should.be.fulfilled
await ambBridgeContract.executeMessageCall(
contract.address,
otherSideMediator.address,
data,
exampleMessageId,
1000000
).should.be.fulfilled
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
// Then
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnForeign)
// Then
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnForeign)
const event = await getEvents(contract, { event: 'TokensBridged' })
expect(event.length).to.be.equal(1)
expect(event[0].returnValues.recipient).to.be.equal(user)
expect(event[0].returnValues.value).to.be.equal(valueOnHome.toString())
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
const event = await getEvents(contract, { event: 'TokensBridged' })
expect(event.length).to.be.equal(1)
expect(event[0].returnValues.recipient).to.be.equal(user)
expect(event[0].returnValues.value).to.be.equal(valueOnHome.toString())
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
}
it('should revert when out of execution limits on message from amb', async () => {
// Given

View File

@ -132,6 +132,18 @@ function shouldBehaveLikeBasicAMBErc677ToErc677(otherSideMediatorContract, accou
)
.should.be.rejectedWith(ERROR_MSG)
// not valid decimal shift
await contract.initialize(
bridgeContract.address,
mediatorContract.address,
erc677Token.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
100,
owner
).should.be.rejected
const { logs } = await contract.initialize(
bridgeContract.address,
mediatorContract.address,

View File

@ -192,64 +192,65 @@ contract('ForeignAMBErc677ToErc677', async accounts => {
expect(TokensBridgedEvent[0].returnValues.value).to.be.equal(oneEther.toString())
expect(TokensBridgedEvent[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
it('should transfer locked tokens on message from amb with decimal shift of two', async () => {
// Given
const decimalShiftTwo = 2
erc677Token = await ERC677BridgeToken.new('test', 'TST', 16)
for (const decimalShift of [2, -1]) {
it(`should transfer locked tokens on message from amb with decimal shift of ${decimalShift}`, async () => {
// Given
erc677Token = await ERC677BridgeToken.new('test', 'TST', 16)
foreignBridge = await ForeignAMBErc677ToErc677.new()
await foreignBridge.initialize(
ambBridgeContract.address,
mediatorContract.address,
erc677Token.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShiftTwo,
owner
).should.be.fulfilled
await erc677Token.mint(foreignBridge.address, twoEthers, { from: owner }).should.be.fulfilled
await erc677Token.transferOwnership(foreignBridge.address)
foreignBridge = await ForeignAMBErc677ToErc677.new()
await foreignBridge.initialize(
ambBridgeContract.address,
mediatorContract.address,
erc677Token.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShift,
owner
).should.be.fulfilled
await erc677Token.mint(foreignBridge.address, twoEthers, { from: owner }).should.be.fulfilled
await erc677Token.transferOwnership(foreignBridge.address)
const currentDay = await foreignBridge.getCurrentDay()
expect(await foreignBridge.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const initialEvents = await getEvents(erc677Token, { event: 'Transfer' })
expect(initialEvents.length).to.be.equal(0)
expect(await erc677Token.balanceOf(foreignBridge.address)).to.be.bignumber.equal(twoEthers)
expect(await erc677Token.balanceOf(user)).to.be.bignumber.equal(ZERO)
const currentDay = await foreignBridge.getCurrentDay()
expect(await foreignBridge.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const initialEvents = await getEvents(erc677Token, { event: 'Transfer' })
expect(initialEvents.length).to.be.equal(0)
expect(await erc677Token.balanceOf(foreignBridge.address)).to.be.bignumber.equal(twoEthers)
expect(await erc677Token.balanceOf(user)).to.be.bignumber.equal(ZERO)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const data = await foreignBridge.contract.methods.handleBridgedTokens(user, valueOnHome.toString()).encodeABI()
const data = await foreignBridge.contract.methods.handleBridgedTokens(user, valueOnHome.toString()).encodeABI()
// message must be generated by mediator contract on the other network
await ambBridgeContract.executeMessageCall(foreignBridge.address, owner, data, otherMessageId, 1000000).should.be
.fulfilled
// message must be generated by mediator contract on the other network
await ambBridgeContract.executeMessageCall(foreignBridge.address, owner, data, otherMessageId, 1000000).should
.be.fulfilled
expect(await ambBridgeContract.messageCallStatus(otherMessageId)).to.be.equal(false)
expect(await ambBridgeContract.messageCallStatus(otherMessageId)).to.be.equal(false)
await ambBridgeContract.executeMessageCall(
foreignBridge.address,
mediatorContract.address,
data,
exampleMessageId,
1000000
).should.be.fulfilled
await ambBridgeContract.executeMessageCall(
foreignBridge.address,
mediatorContract.address,
data,
exampleMessageId,
1000000
).should.be.fulfilled
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
// Then
expect(await foreignBridge.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnHome)
expect(await erc677Token.balanceOf(foreignBridge.address)).to.be.bignumber.equal(twoEthers.sub(valueOnForeign))
expect(await erc677Token.balanceOf(user)).to.be.bignumber.equal(valueOnForeign)
// Then
expect(await foreignBridge.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnHome)
expect(await erc677Token.balanceOf(foreignBridge.address)).to.be.bignumber.equal(twoEthers.sub(valueOnForeign))
expect(await erc677Token.balanceOf(user)).to.be.bignumber.equal(valueOnForeign)
const TokensBridgedEvent = await getEvents(foreignBridge, { event: 'TokensBridged' })
expect(TokensBridgedEvent.length).to.be.equal(1)
expect(TokensBridgedEvent[0].returnValues.recipient).to.be.equal(user)
expect(TokensBridgedEvent[0].returnValues.value).to.be.equal(valueOnForeign.toString())
expect(TokensBridgedEvent[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
const TokensBridgedEvent = await getEvents(foreignBridge, { event: 'TokensBridged' })
expect(TokensBridgedEvent.length).to.be.equal(1)
expect(TokensBridgedEvent[0].returnValues.recipient).to.be.equal(user)
expect(TokensBridgedEvent[0].returnValues.value).to.be.equal(valueOnForeign.toString())
expect(TokensBridgedEvent[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
}
it('should emit AmountLimitExceeded and not transfer tokens when out of execution limits', async () => {
// Given
const currentDay = await foreignBridge.getCurrentDay()

View File

@ -200,66 +200,67 @@ contract('HomeAMBErc677ToErc677', async accounts => {
expect(TokensBridgedEvent[0].returnValues.value).to.be.equal(oneEther.toString())
expect(TokensBridgedEvent[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
it('should mint tokens on message from amb with decimal shift of two', async () => {
// Given
const decimalShiftTwo = 2
erc677Token = await ERC677BridgeToken.new('test', 'TST', 18)
for (const decimalShift of [2, -1]) {
it(`should mint tokens on message from amb with decimal shift of ${decimalShift}`, async () => {
// Given
erc677Token = await ERC677BridgeToken.new('test', 'TST', 18)
homeBridge = await HomeAMBErc677ToErc677.new()
await homeBridge.initialize(
ambBridgeContract.address,
mediatorContract.address,
erc677Token.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShiftTwo,
owner
).should.be.fulfilled
await erc677Token.transferOwnership(homeBridge.address)
homeBridge = await HomeAMBErc677ToErc677.new()
await homeBridge.initialize(
ambBridgeContract.address,
mediatorContract.address,
erc677Token.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShift,
owner
).should.be.fulfilled
await erc677Token.transferOwnership(homeBridge.address)
const currentDay = await homeBridge.getCurrentDay()
expect(await homeBridge.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const initialEvents = await getEvents(erc677Token, { event: 'Mint' })
expect(initialEvents.length).to.be.equal(0)
expect(await erc677Token.totalSupply()).to.be.bignumber.equal(ZERO)
const currentDay = await homeBridge.getCurrentDay()
expect(await homeBridge.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const initialEvents = await getEvents(erc677Token, { event: 'Mint' })
expect(initialEvents.length).to.be.equal(0)
expect(await erc677Token.totalSupply()).to.be.bignumber.equal(ZERO)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const data = await homeBridge.contract.methods.handleBridgedTokens(user, valueOnForeign.toString()).encodeABI()
const data = await homeBridge.contract.methods.handleBridgedTokens(user, valueOnForeign.toString()).encodeABI()
// message must be generated by mediator contract on the other network
await ambBridgeContract.executeMessageCall(homeBridge.address, owner, data, otherMessageId, 1000000).should.be
.fulfilled
// message must be generated by mediator contract on the other network
await ambBridgeContract.executeMessageCall(homeBridge.address, owner, data, otherMessageId, 1000000).should.be
.fulfilled
expect(await ambBridgeContract.messageCallStatus(otherMessageId)).to.be.equal(false)
expect(await ambBridgeContract.messageCallStatus(otherMessageId)).to.be.equal(false)
await ambBridgeContract.executeMessageCall(
homeBridge.address,
mediatorContract.address,
data,
exampleMessageId,
1000000
).should.be.fulfilled
await ambBridgeContract.executeMessageCall(
homeBridge.address,
mediatorContract.address,
data,
exampleMessageId,
1000000
).should.be.fulfilled
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
// Then
expect(await homeBridge.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnForeign)
const events = await getEvents(erc677Token, { event: 'Mint' })
expect(events.length).to.be.equal(1)
expect(events[0].returnValues.to).to.be.equal(user)
expect(events[0].returnValues.amount).to.be.equal(valueOnHome.toString())
expect(await erc677Token.totalSupply()).to.be.bignumber.equal(valueOnHome)
expect(await erc677Token.balanceOf(user)).to.be.bignumber.equal(valueOnHome)
// Then
expect(await homeBridge.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnForeign)
const events = await getEvents(erc677Token, { event: 'Mint' })
expect(events.length).to.be.equal(1)
expect(events[0].returnValues.to).to.be.equal(user)
expect(events[0].returnValues.amount).to.be.equal(valueOnHome.toString())
expect(await erc677Token.totalSupply()).to.be.bignumber.equal(valueOnHome)
expect(await erc677Token.balanceOf(user)).to.be.bignumber.equal(valueOnHome)
const TokensBridgedEvent = await getEvents(homeBridge, { event: 'TokensBridged' })
expect(TokensBridgedEvent.length).to.be.equal(1)
expect(TokensBridgedEvent[0].returnValues.recipient).to.be.equal(user)
expect(TokensBridgedEvent[0].returnValues.value).to.be.equal(valueOnHome.toString())
expect(TokensBridgedEvent[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
const TokensBridgedEvent = await getEvents(homeBridge, { event: 'TokensBridged' })
expect(TokensBridgedEvent.length).to.be.equal(1)
expect(TokensBridgedEvent[0].returnValues.recipient).to.be.equal(user)
expect(TokensBridgedEvent[0].returnValues.value).to.be.equal(valueOnHome.toString())
expect(TokensBridgedEvent[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
}
it('should emit AmountLimitExceeded and not mint tokens when out of execution limits', async () => {
// Given
const currentDay = await homeBridge.getCurrentDay()

View File

@ -198,6 +198,19 @@ contract('ForeignAMBNativeToErc20', async accounts => {
)
.should.be.rejectedWith(ERROR_MSG)
// not valid decimal shift
await contract.initialize(
ambBridgeContract.address,
otherSideMediatorContract.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
100,
owner,
token.address,
feeManager.address
).should.be.rejected
const { logs } = await contract.initialize(
ambBridgeContract.address,
otherSideMediatorContract.address,
@ -1005,68 +1018,69 @@ contract('ForeignAMBNativeToErc20', async accounts => {
expect(event[0].returnValues.value).to.be.equal(oneEther.toString())
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
it('should mint tokens on message from amb with decimal shift of two', async () => {
// Given
const decimalShiftTwo = 2
token = await ERC677BridgeToken.new('test', 'TST', 16)
for (const decimalShift of [2, -1]) {
it(`should mint tokens on message from amb with decimal shift of ${decimalShift}`, async () => {
// Given
token = await ERC677BridgeToken.new('test', 'TST', 16)
contract = await ForeignAMBNativeToErc20.new()
await contract.initialize(
ambBridgeContract.address,
otherSideMediatorContract.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShiftTwo,
owner,
token.address,
ZERO_ADDRESS
).should.be.fulfilled
contract = await ForeignAMBNativeToErc20.new()
await contract.initialize(
ambBridgeContract.address,
otherSideMediatorContract.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShift,
owner,
token.address,
ZERO_ADDRESS
).should.be.fulfilled
await token.transferOwnership(contract.address)
await token.transferOwnership(contract.address)
const currentDay = await contract.getCurrentDay()
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const initialEvents = await getEvents(token, { event: 'Mint' })
expect(initialEvents.length).to.be.equal(0)
expect(await token.totalSupply()).to.be.bignumber.equal(ZERO)
const currentDay = await contract.getCurrentDay()
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const initialEvents = await getEvents(token, { event: 'Mint' })
expect(initialEvents.length).to.be.equal(0)
expect(await token.totalSupply()).to.be.bignumber.equal(ZERO)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const data = await contract.contract.methods.handleBridgedTokens(user, valueOnHome.toString()).encodeABI()
const data = await contract.contract.methods.handleBridgedTokens(user, valueOnHome.toString()).encodeABI()
// message must be generated by mediator contract on the other network
await ambBridgeContract.executeMessageCall(contract.address, owner, data, failedMessageId, 1000000).should.be
.fulfilled
// message must be generated by mediator contract on the other network
await ambBridgeContract.executeMessageCall(contract.address, owner, data, failedMessageId, 1000000).should.be
.fulfilled
expect(await ambBridgeContract.messageCallStatus(failedMessageId)).to.be.equal(false)
expect(await ambBridgeContract.messageCallStatus(failedMessageId)).to.be.equal(false)
await ambBridgeContract.executeMessageCall(
contract.address,
otherSideMediatorContract.address,
data,
exampleMessageId,
1000000
).should.be.fulfilled
await ambBridgeContract.executeMessageCall(
contract.address,
otherSideMediatorContract.address,
data,
exampleMessageId,
1000000
).should.be.fulfilled
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
// Then
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnHome)
const events = await getEvents(token, { event: 'Mint' })
expect(events.length).to.be.equal(1)
expect(events[0].returnValues.to).to.be.equal(user)
expect(events[0].returnValues.amount).to.be.equal(valueOnForeign.toString())
expect(await token.totalSupply()).to.be.bignumber.equal(valueOnForeign)
expect(await token.balanceOf(user)).to.be.bignumber.equal(valueOnForeign)
// Then
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnHome)
const events = await getEvents(token, { event: 'Mint' })
expect(events.length).to.be.equal(1)
expect(events[0].returnValues.to).to.be.equal(user)
expect(events[0].returnValues.amount).to.be.equal(valueOnForeign.toString())
expect(await token.totalSupply()).to.be.bignumber.equal(valueOnForeign)
expect(await token.balanceOf(user)).to.be.bignumber.equal(valueOnForeign)
const event = await getEvents(contract, { event: 'TokensBridged' })
expect(event.length).to.be.equal(1)
expect(event[0].returnValues.recipient).to.be.equal(user)
expect(event[0].returnValues.value).to.be.equal(valueOnForeign.toString())
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
const event = await getEvents(contract, { event: 'TokensBridged' })
expect(event.length).to.be.equal(1)
expect(event[0].returnValues.recipient).to.be.equal(user)
expect(event[0].returnValues.value).to.be.equal(valueOnForeign.toString())
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
}
it('should revert when out of execution limits on message from amb', async () => {
// Given
const currentDay = await contract.getCurrentDay()

View File

@ -165,6 +165,18 @@ contract('HomeAMBNativeToErc20', async accounts => {
)
.should.be.rejectedWith(ERROR_MSG)
// not valid decimal shift
await contract.initialize(
ambBridgeContract.address,
otherSideMediatorContract.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
100,
owner,
feeManager.address
).should.be.rejected
const { logs } = await contract.initialize(
ambBridgeContract.address,
otherSideMediatorContract.address,
@ -582,73 +594,74 @@ contract('HomeAMBNativeToErc20', async accounts => {
expect(event[0].returnValues.value).to.be.equal(oneEther.toString())
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
it('should unlock native tokens on message from amb with decimal shift of two', async () => {
// Given
contract = await HomeAMBNativeToErc20.new()
const decimalShiftTwo = 2
for (const decimalShift of [2, -1]) {
it(`should unlock native tokens on message from amb with decimal shift of ${decimalShift}`, async () => {
// Given
contract = await HomeAMBNativeToErc20.new()
await contract.initialize(
ambBridgeContract.address,
otherSideMediatorContract.address,
[dailyLimit, maxPerTx, minPerTx],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShiftTwo,
owner,
ZERO_ADDRESS
).should.be.fulfilled
await contract.initialize(
ambBridgeContract.address,
otherSideMediatorContract.address,
[dailyLimit, maxPerTx, ether('0.001')],
[executionDailyLimit, executionMaxPerTx],
maxGasPerTx,
decimalShift,
owner,
ZERO_ADDRESS
).should.be.fulfilled
const valueOnForeign = ether('0.01')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const valueOnForeign = ether('0.01')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
// send native tokens to the contract
await contract.sendTransaction({
from: user2,
value: valueOnHome
}).should.be.fulfilled
// send native tokens to the contract
await contract.sendTransaction({
from: user2,
value: valueOnHome
}).should.be.fulfilled
expect(toBN(await web3.eth.getBalance(contract.address))).to.be.bignumber.equal(valueOnHome)
expect(toBN(await web3.eth.getBalance(contract.address))).to.be.bignumber.equal(valueOnHome)
const currentDay = await contract.getCurrentDay()
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const currentDay = await contract.getCurrentDay()
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(ZERO)
// When
// can't be called by user
await contract.handleBridgedTokens(user, valueOnForeign, { from: user }).should.be.rejectedWith(ERROR_MSG)
// can't be called by owner
await contract.handleBridgedTokens(user, valueOnForeign, { from: owner }).should.be.rejectedWith(ERROR_MSG)
// When
// can't be called by user
await contract.handleBridgedTokens(user, valueOnForeign, { from: user }).should.be.rejectedWith(ERROR_MSG)
// can't be called by owner
await contract.handleBridgedTokens(user, valueOnForeign, { from: owner }).should.be.rejectedWith(ERROR_MSG)
const data = await contract.contract.methods.handleBridgedTokens(user, valueOnForeign.toString()).encodeABI()
const data = await contract.contract.methods.handleBridgedTokens(user, valueOnForeign.toString()).encodeABI()
// message must be generated by mediator contract on the other network, here owner is the sender
await ambBridgeContract.executeMessageCall(contract.address, owner, data, failedMessageId, '1000000').should.be
.fulfilled
// message must be generated by mediator contract on the other network, here owner is the sender
await ambBridgeContract.executeMessageCall(contract.address, owner, data, failedMessageId, '1000000').should.be
.fulfilled
expect(await ambBridgeContract.messageCallStatus(failedMessageId)).to.be.equal(false)
expect(await ambBridgeContract.messageCallStatus(failedMessageId)).to.be.equal(false)
const balanceUserBefore = toBN(await web3.eth.getBalance(user))
const balanceUserBefore = toBN(await web3.eth.getBalance(user))
await ambBridgeContract.executeMessageCall(
contract.address,
otherSideMediatorContract.address,
data,
exampleMessageId,
'1000000'
).should.be.fulfilled
await ambBridgeContract.executeMessageCall(
contract.address,
otherSideMediatorContract.address,
data,
exampleMessageId,
'1000000'
).should.be.fulfilled
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
expect(await ambBridgeContract.messageCallStatus(exampleMessageId)).to.be.equal(true)
// Then
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnForeign)
expect(toBN(await web3.eth.getBalance(contract.address))).to.be.bignumber.equal(ZERO)
expect(toBN(await web3.eth.getBalance(user))).to.be.bignumber.equal(balanceUserBefore.add(valueOnHome))
// Then
expect(await contract.totalExecutedPerDay(currentDay)).to.be.bignumber.equal(valueOnForeign)
expect(toBN(await web3.eth.getBalance(contract.address))).to.be.bignumber.equal(ZERO)
expect(toBN(await web3.eth.getBalance(user))).to.be.bignumber.equal(balanceUserBefore.add(valueOnHome))
const event = await getEvents(contract, { event: 'TokensBridged' })
expect(event.length).to.be.equal(1)
expect(event[0].returnValues.recipient).to.be.equal(user)
expect(event[0].returnValues.value).to.be.equal(valueOnHome.toString())
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
const event = await getEvents(contract, { event: 'TokensBridged' })
expect(event.length).to.be.equal(1)
expect(event[0].returnValues.recipient).to.be.equal(user)
expect(event[0].returnValues.value).to.be.equal(valueOnHome.toString())
expect(event[0].returnValues.messageId).to.be.equal(exampleMessageId)
})
}
it('should revert when out of execution limits on message from amb', async () => {
// Given
// send native tokens to the contract

View File

@ -154,6 +154,18 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
)
.should.be.rejectedWith(ERROR_MSG)
// not valid decimal shift
await foreignBridge.initialize(
validatorContract.address,
token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
100
).should.be.rejected
const { logs } = await foreignBridge.initialize(
validatorContract.address,
token.address,
@ -771,130 +783,132 @@ contract('ForeignBridge_ERC20_to_ERC20', async accounts => {
})
})
describe('#decimalShift', async () => {
const decimalShiftTwo = 2
it('Home to Foreign: withdraw with 1 signature with a decimalShift of 2', async () => {
const valueOnForeign = toBN('1000')
// Value is decimals shifted from foreign to home: Native on home = 16+2 shift = 18 decimals
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const foreignBridge = await ForeignBridge.new()
token = await ERC677BridgeToken.new('Some ERC20', 'RSZT', 16)
await foreignBridge.initialize(
validatorContract.address,
token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShiftTwo
)
await token.mint(foreignBridge.address, valueOnForeign)
for (const decimalShift of [2, -1]) {
it(`Home to Foreign: withdraw with 1 signature with a decimalShift of ${decimalShift}`, async () => {
const valueOnForeign = toBN('1000')
// Value is decimals shifted from foreign to home: Native on home = 16+2 shift = 18 decimals
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const foreignBridge = await ForeignBridge.new()
token = await ERC677BridgeToken.new('Some ERC20', 'RSZT', 16)
await foreignBridge.initialize(
validatorContract.address,
token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShift
)
await token.mint(foreignBridge.address, valueOnForeign)
const recipientAccount = accounts[3]
const balanceBefore = await token.balanceOf(recipientAccount)
const recipientAccount = accounts[3]
const balanceBefore = await token.balanceOf(recipientAccount)
const transactionHash = '0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80'
const message = createMessage(recipientAccount, valueOnHome, transactionHash, foreignBridge.address)
const signature = await sign(authorities[0], message)
const vrs = signatureToVRS(signature)
const oneSignature = packSignatures([vrs])
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
logs[0].event.should.be.equal('RelayedMessage')
logs[0].args.recipient.should.be.equal(recipientAccount)
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
const transactionHash = '0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80'
const message = createMessage(recipientAccount, valueOnHome, transactionHash, foreignBridge.address)
const signature = await sign(authorities[0], message)
const vrs = signatureToVRS(signature)
const oneSignature = packSignatures([vrs])
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
logs[0].event.should.be.equal('RelayedMessage')
logs[0].args.recipient.should.be.equal(recipientAccount)
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
const balanceAfter = await token.balanceOf(recipientAccount)
const balanceAfterBridge = await token.balanceOf(foreignBridge.address)
balanceAfter.should.be.bignumber.equal(balanceBefore.add(valueOnForeign))
balanceAfterBridge.should.be.bignumber.equal(ZERO)
true.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
})
it('Home to Foreign : withdraw works with 5 validators and 3 required signatures with a decimalShift of 2', async () => {
const valueOnForeign = toBN('1000')
// Value is decimals shifted from foreign to home: Native on home = 16+2 shift = 18 decimals
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const recipient = accounts[8]
const authoritiesFiveAccs = [accounts[1], accounts[2], accounts[3], accounts[4], accounts[5]]
const ownerOfValidators = accounts[0]
const validatorContractWith3Signatures = await BridgeValidators.new()
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
const erc20Token = await ERC677BridgeToken.new('Some ERC20', 'RSZT', 16)
const balanceAfter = await token.balanceOf(recipientAccount)
const balanceAfterBridge = await token.balanceOf(foreignBridge.address)
balanceAfter.should.be.bignumber.equal(balanceBefore.add(valueOnForeign))
balanceAfterBridge.should.be.bignumber.equal(ZERO)
true.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
})
it('Home to Foreign : withdraw works with 5 validators and 3 required signatures with a decimalShift of 2', async () => {
const valueOnForeign = toBN('1000')
// Value is decimals shifted from foreign to home: Native on home = 16+2 shift = 18 decimals
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const recipient = accounts[8]
const authoritiesFiveAccs = [accounts[1], accounts[2], accounts[3], accounts[4], accounts[5]]
const ownerOfValidators = accounts[0]
const validatorContractWith3Signatures = await BridgeValidators.new()
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
const erc20Token = await ERC677BridgeToken.new('Some ERC20', 'RSZT', 16)
const foreignBridgeWithThreeSigs = await ForeignBridge.new()
const foreignBridgeWithThreeSigs = await ForeignBridge.new()
await foreignBridgeWithThreeSigs.initialize(
validatorContractWith3Signatures.address,
erc20Token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShiftTwo
)
await erc20Token.mint(foreignBridgeWithThreeSigs.address, valueOnForeign)
await foreignBridgeWithThreeSigs.initialize(
validatorContractWith3Signatures.address,
erc20Token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShift
)
await erc20Token.mint(foreignBridgeWithThreeSigs.address, valueOnForeign)
const balanceBeforeRecipient = await erc20Token.balanceOf(recipient)
const balanceBeforeBridge = await erc20Token.balanceOf(foreignBridgeWithThreeSigs.address)
const balanceBeforeRecipient = await erc20Token.balanceOf(recipient)
const balanceBeforeBridge = await erc20Token.balanceOf(foreignBridgeWithThreeSigs.address)
const txHash = '0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121'
const message = createMessage(recipient, valueOnHome, txHash, foreignBridgeWithThreeSigs.address)
const txHash = '0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121'
const message = createMessage(recipient, valueOnHome, txHash, foreignBridgeWithThreeSigs.address)
// signature 1
const signature = await sign(authoritiesFiveAccs[0], message)
const vrs = signatureToVRS(signature)
// signature 1
const signature = await sign(authoritiesFiveAccs[0], message)
const vrs = signatureToVRS(signature)
// signature 2
const signature2 = await sign(authoritiesFiveAccs[1], message)
const vrs2 = signatureToVRS(signature2)
// signature 2
const signature2 = await sign(authoritiesFiveAccs[1], message)
const vrs2 = signatureToVRS(signature2)
// signature 3
const signature3 = await sign(authoritiesFiveAccs[2], message)
const vrs3 = signatureToVRS(signature3)
// signature 3
const signature3 = await sign(authoritiesFiveAccs[2], message)
const vrs3 = signatureToVRS(signature3)
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(message, threeSignatures).should.be.fulfilled
logs[0].event.should.be.equal('RelayedMessage')
logs[0].args.recipient.should.be.equal(recipient)
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
true.should.be.equal(await foreignBridgeWithThreeSigs.relayedMessages(txHash))
const balanceAfterRecipient = await erc20Token.balanceOf(recipient)
balanceAfterRecipient.should.be.bignumber.equal(balanceBeforeRecipient.add(valueOnForeign))
const balanceAfterBridge = await erc20Token.balanceOf(foreignBridgeWithThreeSigs.address)
balanceBeforeBridge.should.be.bignumber.equal(balanceAfterBridge.add(valueOnForeign))
})
it('Foreign to Home: no impact in UserRequestForAffirmation event signal for bridges oracles with a decimalShift of 2.', async () => {
const value = halfEther
const owner = accounts[3]
const user = accounts[4]
token = await ERC677BridgeToken.new('TEST', 'TST', 16, { from: owner })
const foreignBridge = await ForeignBridgeErc677ToErc677.new()
await foreignBridge.initialize(
validatorContract.address,
token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShiftTwo
)
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(message, threeSignatures).should.be
.fulfilled
logs[0].event.should.be.equal('RelayedMessage')
logs[0].args.recipient.should.be.equal(recipient)
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
true.should.be.equal(await foreignBridgeWithThreeSigs.relayedMessages(txHash))
const balanceAfterRecipient = await erc20Token.balanceOf(recipient)
balanceAfterRecipient.should.be.bignumber.equal(balanceBeforeRecipient.add(valueOnForeign))
const balanceAfterBridge = await erc20Token.balanceOf(foreignBridgeWithThreeSigs.address)
balanceBeforeBridge.should.be.bignumber.equal(balanceAfterBridge.add(valueOnForeign))
})
it('Foreign to Home: no impact in UserRequestForAffirmation event signal for bridges oracles with a decimalShift of 2.', async () => {
const value = halfEther
const owner = accounts[3]
const user = accounts[4]
token = await ERC677BridgeToken.new('TEST', 'TST', 16, { from: owner })
const foreignBridge = await ForeignBridgeErc677ToErc677.new()
await foreignBridge.initialize(
validatorContract.address,
token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShift
)
await token.mint(user, value, { from: owner }).should.be.fulfilled
await token.transferOwnership(foreignBridge.address, { from: owner })
await foreignBridge.onTokenTransfer(user, value, '0x', { from: owner }).should.be.rejectedWith(ERROR_MSG)
await token.mint(user, value, { from: owner }).should.be.fulfilled
await token.transferOwnership(foreignBridge.address, { from: owner })
await foreignBridge.onTokenTransfer(user, value, '0x', { from: owner }).should.be.rejectedWith(ERROR_MSG)
await token.transferAndCall(foreignBridge.address, value, '0x', { from: user }).should.be.fulfilled
expect(await token.totalSupply()).to.be.bignumber.equal(value)
expect(await token.balanceOf(user)).to.be.bignumber.equal(ZERO)
expect(await token.balanceOf(foreignBridge.address)).to.be.bignumber.equal(value)
await token.transferAndCall(foreignBridge.address, value, '0x', { from: user }).should.be.fulfilled
expect(await token.totalSupply()).to.be.bignumber.equal(value)
expect(await token.balanceOf(user)).to.be.bignumber.equal(ZERO)
expect(await token.balanceOf(foreignBridge.address)).to.be.bignumber.equal(value)
const events = await getEvents(foreignBridge, { event: 'UserRequestForAffirmation' })
expect(events[0].returnValues.recipient).to.be.equal(user)
expect(toBN(events[0].returnValues.value)).to.be.bignumber.equal(value)
})
const events = await getEvents(foreignBridge, { event: 'UserRequestForAffirmation' })
expect(events[0].returnValues.recipient).to.be.equal(user)
expect(toBN(events[0].returnValues.value)).to.be.bignumber.equal(value)
})
}
})
describe('#relayTokens', () => {
const value = ether('0.25')

View File

@ -216,6 +216,19 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
decimalShiftZero
)
.should.be.rejectedWith(ERROR_MSG)
// not valid decimal shift
await homeContract.initialize(
validatorContract.address,
['3', '2', '1'],
gasPrice,
requireBlockConfirmations,
token.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
100
).should.be.rejected
await homeContract.initialize(
validatorContract.address,
['3', '2', '1'],
@ -1981,86 +1994,87 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
})
})
describe('#decimals Shift', async () => {
const decimalShiftTwo = 2
it('Foreign to Home: works with 5 validators and 3 required signatures with decimal shift 2', async () => {
const recipient = accounts[8]
const authoritiesFiveAccs = [accounts[1], accounts[2], accounts[3], accounts[4], accounts[5]]
const ownerOfValidators = accounts[0]
const validatorContractWith3Signatures = await BridgeValidators.new()
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
const token = await ERC677BridgeToken.new('Some ERC20', 'RSZT', 16)
for (const decimalShift of [2, -1]) {
it(`Foreign to Home: works with 5 validators and 3 required signatures with decimal shift ${decimalShift}`, async () => {
const recipient = accounts[8]
const authoritiesFiveAccs = [accounts[1], accounts[2], accounts[3], accounts[4], accounts[5]]
const ownerOfValidators = accounts[0]
const validatorContractWith3Signatures = await BridgeValidators.new()
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
const token = await ERC677BridgeToken.new('Some ERC20', 'RSZT', 16)
const homeBridgeWithThreeSigs = await HomeBridge.new()
await homeBridgeWithThreeSigs.initialize(
validatorContractWith3Signatures.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
token.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShiftTwo
)
await token.transferOwnership(homeBridgeWithThreeSigs.address)
const homeBridgeWithThreeSigs = await HomeBridge.new()
await homeBridgeWithThreeSigs.initialize(
validatorContractWith3Signatures.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
token.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShift
)
await token.transferOwnership(homeBridgeWithThreeSigs.address)
const valueOnForeign = toBN('1000')
// Value is decimals shifted from foreign to home: Native on home = 16+2 shift = 18 decimals
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const balanceBeforeRecipient = await token.balanceOf(recipient)
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'
const valueOnForeign = toBN('1000')
// Value is decimals shifted from foreign to home: Native on home = 16+2 shift = 18 decimals
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const balanceBeforeRecipient = await token.balanceOf(recipient)
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'
const { logs } = await homeBridgeWithThreeSigs.executeAffirmation(recipient, valueOnForeign, transactionHash, {
from: authoritiesFiveAccs[0]
}).should.be.fulfilled
expectEventInLogs(logs, 'SignedForAffirmation', {
signer: authorities[0],
transactionHash
const { logs } = await homeBridgeWithThreeSigs.executeAffirmation(recipient, valueOnForeign, transactionHash, {
from: authoritiesFiveAccs[0]
}).should.be.fulfilled
expectEventInLogs(logs, 'SignedForAffirmation', {
signer: authorities[0],
transactionHash
})
await homeBridgeWithThreeSigs.executeAffirmation(recipient, valueOnForeign, transactionHash, {
from: authoritiesFiveAccs[1]
}).should.be.fulfilled
const thirdSignature = await homeBridgeWithThreeSigs.executeAffirmation(
recipient,
valueOnForeign,
transactionHash,
{ from: authoritiesFiveAccs[2] }
).should.be.fulfilled
expectEventInLogs(thirdSignature.logs, 'AffirmationCompleted', {
recipient,
value: valueOnForeign,
transactionHash
})
const balanceAfterRecipient = await token.balanceOf(recipient)
balanceAfterRecipient.should.be.bignumber.equal(balanceBeforeRecipient.add(valueOnHome))
})
it(`Foreign to Home: test decimal shift ${decimalShift}, no impact on UserRequestForSignature value`, async () => {
// Given
const homeBridge = await HomeBridge.new()
token = await ERC677BridgeToken.new('Some ERC20', 'TEST', 16)
const owner = accounts[0]
const user = accounts[4]
await homeBridge.initialize(
validatorContract.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
token.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShift
).should.be.fulfilled
const value = halfEther
await token.mint(user, value, { from: owner }).should.be.fulfilled
await homeBridgeWithThreeSigs.executeAffirmation(recipient, valueOnForeign, transactionHash, {
from: authoritiesFiveAccs[1]
}).should.be.fulfilled
const thirdSignature = await homeBridgeWithThreeSigs.executeAffirmation(
recipient,
valueOnForeign,
transactionHash,
{ from: authoritiesFiveAccs[2] }
).should.be.fulfilled
// When
await token.transferAndCall(homeBridge.address, value, '0x', { from: user }).should.be.fulfilled
expectEventInLogs(thirdSignature.logs, 'AffirmationCompleted', {
recipient,
value: valueOnForeign,
transactionHash
// Then
const events = await getEvents(homeBridge, { event: 'UserRequestForSignature' })
expect(events[0].returnValues.recipient).to.be.equal(user)
expect(toBN(events[0].returnValues.value)).to.be.bignumber.equal(value)
})
const balanceAfterRecipient = await token.balanceOf(recipient)
balanceAfterRecipient.should.be.bignumber.equal(balanceBeforeRecipient.add(valueOnHome))
})
it('Foreign to Home: test decimal shift 2, no impact on UserRequestForSignature value', async () => {
// Given
const homeBridge = await HomeBridge.new()
token = await ERC677BridgeToken.new('Some ERC20', 'TEST', 16)
const owner = accounts[0]
const user = accounts[4]
await homeBridge.initialize(
validatorContract.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
token.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShiftTwo
).should.be.fulfilled
const value = halfEther
await token.mint(user, value, { from: owner }).should.be.fulfilled
// When
await token.transferAndCall(homeBridge.address, value, '0x', { from: user }).should.be.fulfilled
// Then
const events = await getEvents(homeBridge, { event: 'UserRequestForSignature' })
expect(events[0].returnValues.recipient).to.be.equal(user)
expect(toBN(events[0].returnValues.value)).to.be.bignumber.equal(value)
})
}
})
})

View File

@ -199,6 +199,19 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
ZERO_ADDRESS
).should.be.rejected
// not valid decimal shift
await foreignBridge.initialize(
validatorContract.address,
token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
'100',
otherSideBridge.address
).should.be.rejected
const { logs } = await foreignBridge.initialize(
validatorContract.address,
token.address,
@ -776,108 +789,108 @@ contract('ForeignBridge_ERC20_to_Native', async accounts => {
})
})
describe('#decimalShift', async () => {
const decimalShiftTwo = 2
it('Home to Foreign: withdraw with 1 signature with a decimalShift of 2', async () => {
// From a foreign a token erc token 16 decimals.
const token = await ERC677BridgeToken.new('Some ERC20', 'RSZT', 16)
const valueOnForeign = toBN('1000')
// Value is decimals shifted from foreign to home: Native on home = 16+2 shift = 18 decimals
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
for (const decimalShift of [2, -1]) {
it(`Home to Foreign: withdraw with 1 signature with a decimalShift of ${decimalShift}`, async () => {
// From a foreign a token erc token 16 decimals.
const token = await ERC677BridgeToken.new('Some ERC20', 'RSZT', 16)
const valueOnForeign = toBN('1000')
// Value is decimals shifted from foreign to home: Native on home = 16+2 shift = 18 decimals
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const owner = accounts[0]
const foreignBridgeImpl = await ForeignBridgeErcToNativeMock.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)
const owner = accounts[0]
const foreignBridgeImpl = await ForeignBridgeErcToNativeMock.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,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShiftTwo,
otherSideBridge.address
)
await token.mint(foreignBridge.address, valueOnForeign)
await foreignBridge.initialize(
validatorContract.address,
token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShift,
otherSideBridge.address
)
await token.mint(foreignBridge.address, valueOnForeign)
const recipientAccount = accounts[3]
const balanceBefore = await token.balanceOf(recipientAccount)
const recipientAccount = accounts[3]
const balanceBefore = await token.balanceOf(recipientAccount)
const transactionHash = '0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80'
const message = createMessage(recipientAccount, valueOnHome, transactionHash, foreignBridge.address)
const signature = await sign(authorities[0], message)
const vrs = signatureToVRS(signature)
const oneSignature = packSignatures([vrs])
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
const transactionHash = '0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80'
const message = createMessage(recipientAccount, valueOnHome, transactionHash, foreignBridge.address)
const signature = await sign(authorities[0], message)
const vrs = signatureToVRS(signature)
const oneSignature = packSignatures([vrs])
false.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
const { logs } = await foreignBridge.executeSignatures(message, oneSignature).should.be.fulfilled
logs[0].event.should.be.equal('RelayedMessage')
logs[0].args.recipient.should.be.equal(recipientAccount)
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
const balanceAfter = await token.balanceOf(recipientAccount)
balanceAfter.should.be.bignumber.equal(balanceBefore.add(valueOnForeign))
const balanceAfterBridge = await token.balanceOf(foreignBridge.address)
balanceAfterBridge.should.be.bignumber.equal(ZERO)
true.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
})
it('Home to Foreign: withdraw with 2 minimum signatures with a decimalShift of 2', async () => {
const multisigValidatorContract = await BridgeValidators.new()
const valueOnForeign = toBN('1000')
const decimalShiftTwo = 2
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const token = await ERC677BridgeToken.new('Some ERC20', 'RSZT', 16)
const twoAuthorities = [accounts[0], accounts[1]]
const ownerOfValidatorContract = accounts[3]
const recipient = accounts[8]
await multisigValidatorContract.initialize(2, twoAuthorities, ownerOfValidatorContract, {
from: ownerOfValidatorContract
logs[0].event.should.be.equal('RelayedMessage')
logs[0].args.recipient.should.be.equal(recipientAccount)
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
const balanceAfter = await token.balanceOf(recipientAccount)
balanceAfter.should.be.bignumber.equal(balanceBefore.add(valueOnForeign))
const balanceAfterBridge = await token.balanceOf(foreignBridge.address)
balanceAfterBridge.should.be.bignumber.equal(ZERO)
true.should.be.equal(await foreignBridge.relayedMessages(transactionHash))
})
const foreignBridgeWithMultiSignatures = await ForeignBridgeErcToNativeMock.new()
await foreignBridgeWithMultiSignatures.initialize(
multisigValidatorContract.address,
token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShiftTwo,
otherSideBridge.address,
{ from: ownerOfValidatorContract }
)
await token.mint(foreignBridgeWithMultiSignatures.address, valueOnForeign)
const balanceBefore = await token.balanceOf(recipient)
it(`Home to Foreign: withdraw with 2 minimum signatures with a decimalShift of ${decimalShift}`, async () => {
const multisigValidatorContract = await BridgeValidators.new()
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const token = await ERC677BridgeToken.new('Some ERC20', 'RSZT', 16)
const twoAuthorities = [accounts[0], accounts[1]]
const ownerOfValidatorContract = accounts[3]
const recipient = accounts[8]
await multisigValidatorContract.initialize(2, twoAuthorities, ownerOfValidatorContract, {
from: ownerOfValidatorContract
})
const foreignBridgeWithMultiSignatures = await ForeignBridgeErcToNativeMock.new()
await foreignBridgeWithMultiSignatures.initialize(
multisigValidatorContract.address,
token.address,
requireBlockConfirmations,
gasPrice,
[dailyLimit, maxPerTx, minPerTx],
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShift,
otherSideBridge.address,
{ from: ownerOfValidatorContract }
)
await token.mint(foreignBridgeWithMultiSignatures.address, valueOnForeign)
const txHash = '0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121'
const message = createMessage(recipient, valueOnHome, txHash, foreignBridgeWithMultiSignatures.address)
const balanceBefore = await token.balanceOf(recipient)
// signature 1
const signature = await sign(twoAuthorities[0], message)
const vrs = signatureToVRS(signature)
const txHash = '0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121'
const message = createMessage(recipient, valueOnHome, txHash, foreignBridgeWithMultiSignatures.address)
// signature 2
const signature2 = await sign(twoAuthorities[1], message)
const vrs2 = signatureToVRS(signature2)
// signature 1
const signature = await sign(twoAuthorities[0], message)
const vrs = signatureToVRS(signature)
const twoSignatures = packSignatures([vrs, vrs2])
// signature 2
const signature2 = await sign(twoAuthorities[1], message)
const vrs2 = signatureToVRS(signature2)
const { logs } = await foreignBridgeWithMultiSignatures.executeSignatures(message, twoSignatures).should.be
.fulfilled
logs[0].event.should.be.equal('RelayedMessage')
logs[0].args.recipient.should.be.equal(recipient)
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
const balanceAfter = await token.balanceOf(recipient)
balanceAfter.should.be.bignumber.equal(balanceBefore.add(valueOnForeign))
const balanceAfterBridge = await token.balanceOf(foreignBridgeWithMultiSignatures.address)
balanceAfterBridge.should.be.bignumber.equal(ZERO)
true.should.be.equal(await foreignBridgeWithMultiSignatures.relayedMessages(txHash))
})
const twoSignatures = packSignatures([vrs, vrs2])
const { logs } = await foreignBridgeWithMultiSignatures.executeSignatures(message, twoSignatures).should.be
.fulfilled
logs[0].event.should.be.equal('RelayedMessage')
logs[0].args.recipient.should.be.equal(recipient)
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
const balanceAfter = await token.balanceOf(recipient)
balanceAfter.should.be.bignumber.equal(balanceBefore.add(valueOnForeign))
const balanceAfterBridge = await token.balanceOf(foreignBridgeWithMultiSignatures.address)
balanceAfterBridge.should.be.bignumber.equal(ZERO)
true.should.be.equal(await foreignBridgeWithMultiSignatures.relayedMessages(txHash))
})
}
})
describe('#relayTokens', () => {
const value = ether('0.25')

View File

@ -279,6 +279,19 @@ contract('HomeBridge_ERC20_to_Native', async accounts => {
decimalShiftZero
)
.should.be.rejectedWith(ERROR_MSG)
// not valid decimal shift
await homeContract.initialize(
validatorContract.address,
['3', '2', '1'],
gasPrice,
requireBlockConfirmations,
blockRewardContract.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
'100'
).should.be.rejected
await homeContract.initialize(
validatorContract.address,
['3', '2', '1'],
@ -3322,127 +3335,128 @@ contract('HomeBridge_ERC20_to_Native', async accounts => {
})
})
describe('#decimals Shift', async () => {
const decimalShiftTwo = 2
it('Foreign to Home: test with 2 signatures required and decimal shift 2', async () => {
await blockRewardContract.sendTransaction({
from: accounts[2],
value: oneEther
}).should.be.fulfilled
const recipient = accounts[5]
const valueOnHome = halfEther
for (const decimalShift of [2, -1]) {
it(`Foreign to Home: test with 2 signatures required and decimal shift ${decimalShift}`, async () => {
await blockRewardContract.sendTransaction({
from: accounts[2],
value: oneEther
}).should.be.fulfilled
const recipient = accounts[5]
const valueOnHome = halfEther
const valueOnForeign = toBN(valueOnHome / 10 ** decimalShiftTwo)
const valueOnForeign = toBN(valueOnHome / 10 ** decimalShift)
const validatorContractWith2Signatures = await BridgeValidators.new()
const authoritiesThreeAccs = [accounts[1], accounts[2], accounts[3]]
const ownerOfValidators = accounts[0]
await validatorContractWith2Signatures.initialize(2, authoritiesThreeAccs, ownerOfValidators)
const homeBridgeWithTwoSigs = await HomeBridge.new()
const currentDay = await homeBridgeWithTwoSigs.getCurrentDay()
const validatorContractWith2Signatures = await BridgeValidators.new()
const authoritiesThreeAccs = [accounts[1], accounts[2], accounts[3]]
const ownerOfValidators = accounts[0]
await validatorContractWith2Signatures.initialize(2, authoritiesThreeAccs, ownerOfValidators)
const homeBridgeWithTwoSigs = await HomeBridge.new()
const currentDay = await homeBridgeWithTwoSigs.getCurrentDay()
await homeBridgeWithTwoSigs.initialize(
validatorContractWith2Signatures.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
blockRewardContract.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShiftTwo
)
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'
const balanceBefore = toBN(await web3.eth.getBalance(recipient))
const totalExecutedPerDayBefore = await homeBridgeWithTwoSigs.totalExecutedPerDay(currentDay)
const msgHash = web3.utils.soliditySha3(recipient, valueOnForeign, transactionHash)
await homeBridgeWithTwoSigs.initialize(
validatorContractWith2Signatures.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
blockRewardContract.address,
[ether('100'), ether('10')],
owner,
decimalShift
)
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'
const balanceBefore = toBN(await web3.eth.getBalance(recipient))
const totalExecutedPerDayBefore = await homeBridgeWithTwoSigs.totalExecutedPerDay(currentDay)
const msgHash = web3.utils.soliditySha3(recipient, valueOnForeign, transactionHash)
const { logs } = await homeBridgeWithTwoSigs.executeAffirmation(recipient, valueOnForeign, transactionHash, {
from: authoritiesThreeAccs[0]
}).should.be.fulfilled
const { logs } = await homeBridgeWithTwoSigs.executeAffirmation(recipient, valueOnForeign, transactionHash, {
from: authoritiesThreeAccs[0]
}).should.be.fulfilled
expectEventInLogs(logs, 'SignedForAffirmation', { signer: authorities[0], transactionHash })
expectEventInLogs(logs, 'SignedForAffirmation', { signer: authorities[0], transactionHash })
const notProcessed = await homeBridgeWithTwoSigs.numAffirmationsSigned(msgHash)
notProcessed.should.be.bignumber.equal('1')
const notProcessed = await homeBridgeWithTwoSigs.numAffirmationsSigned(msgHash)
notProcessed.should.be.bignumber.equal('1')
await homeBridgeWithTwoSigs
.executeAffirmation(recipient, valueOnForeign, transactionHash, { from: authoritiesThreeAccs[0] })
.should.be.rejectedWith(ERROR_MSG)
await homeBridgeWithTwoSigs
.executeAffirmation(recipient, valueOnForeign, transactionHash, { from: authoritiesThreeAccs[0] })
.should.be.rejectedWith(ERROR_MSG)
const secondSignature = await homeBridgeWithTwoSigs.executeAffirmation(
recipient,
valueOnForeign,
transactionHash,
{ from: authoritiesThreeAccs[1] }
).should.be.fulfilled
const balanceAfter = toBN(await web3.eth.getBalance(recipient))
balanceAfter.should.be.bignumber.equal(balanceBefore.add(valueOnHome))
const secondSignature = await homeBridgeWithTwoSigs.executeAffirmation(
recipient,
valueOnForeign,
transactionHash,
{ from: authoritiesThreeAccs[1] }
).should.be.fulfilled
const balanceAfter = toBN(await web3.eth.getBalance(recipient))
balanceAfter.should.be.bignumber.equal(balanceBefore.add(valueOnHome))
const totalExecutedPerDayAfter = await homeBridgeWithTwoSigs.totalExecutedPerDay(currentDay)
totalExecutedPerDayAfter.should.be.bignumber.equal(totalExecutedPerDayBefore.add(valueOnForeign))
const totalExecutedPerDayAfter = await homeBridgeWithTwoSigs.totalExecutedPerDay(currentDay)
totalExecutedPerDayAfter.should.be.bignumber.equal(totalExecutedPerDayBefore.add(valueOnForeign))
expectEventInLogs(secondSignature.logs, 'AffirmationCompleted', {
recipient,
value: valueOnForeign,
transactionHash
expectEventInLogs(secondSignature.logs, 'AffirmationCompleted', {
recipient,
value: valueOnForeign,
transactionHash
})
const senderHash = web3.utils.soliditySha3(authoritiesThreeAccs[0], msgHash)
true.should.be.equal(await homeBridgeWithTwoSigs.affirmationsSigned(senderHash))
const senderHash2 = web3.utils.soliditySha3(authoritiesThreeAccs[1], msgHash)
true.should.be.equal(await homeBridgeWithTwoSigs.affirmationsSigned(senderHash2))
const markedAsProcessed = await homeBridgeWithTwoSigs.numAffirmationsSigned(msgHash)
const processed = toBN(2)
.pow(toBN(255))
.add(toBN(2))
markedAsProcessed.should.be.bignumber.equal(processed)
})
const senderHash = web3.utils.soliditySha3(authoritiesThreeAccs[0], msgHash)
true.should.be.equal(await homeBridgeWithTwoSigs.affirmationsSigned(senderHash))
it(`Home to Foreign: test decimal shift ${decimalShift}, no impact on UserRequestForSignature value`, async () => {
homeContract = await HomeBridge.new()
await homeContract.initialize(
validatorContract.address,
['3', '2', '1'],
gasPrice,
requireBlockConfirmations,
blockRewardContract.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShift
)
const senderHash2 = web3.utils.soliditySha3(authoritiesThreeAccs[1], msgHash)
true.should.be.equal(await homeBridgeWithTwoSigs.affirmationsSigned(senderHash2))
const currentDay = await homeContract.getCurrentDay()
expect(await homeContract.totalSpentPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const markedAsProcessed = await homeBridgeWithTwoSigs.numAffirmationsSigned(msgHash)
const processed = toBN(2)
.pow(toBN(255))
.add(toBN(2))
markedAsProcessed.should.be.bignumber.equal(processed)
})
await blockRewardContract.addMintedTotallyByBridge(10, homeContract.address)
const minted = await blockRewardContract.mintedTotallyByBridge(homeContract.address)
minted.should.be.bignumber.equal('10')
it('Home to Foreign: test decimal shift 2, no impact on UserRequestForSignature value', async () => {
homeContract = await HomeBridge.new()
await homeContract.initialize(
validatorContract.address,
['3', '2', '1'],
gasPrice,
requireBlockConfirmations,
blockRewardContract.address,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShiftTwo
)
const recipientAccount = accounts[1]
const currentDay = await homeContract.getCurrentDay()
expect(await homeContract.totalSpentPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const { logs } = await homeContract.sendTransaction({ from: recipientAccount, value: 1 }).should.be.fulfilled
await blockRewardContract.addMintedTotallyByBridge(10, homeContract.address)
const minted = await blockRewardContract.mintedTotallyByBridge(homeContract.address)
minted.should.be.bignumber.equal('10')
expectEventInLogs(logs, 'UserRequestForSignature', { recipient: recipientAccount, value: toBN(1) })
expect(await homeContract.totalSpentPerDay(currentDay)).to.be.bignumber.equal('1')
expect(await homeContract.totalBurntCoins()).to.be.bignumber.equal('1')
const recipientAccount = accounts[1]
const homeContractBalance = toBN(await web3.eth.getBalance(homeContract.address))
homeContractBalance.should.be.bignumber.equal(ZERO)
const { logs } = await homeContract.sendTransaction({ from: recipientAccount, value: 1 }).should.be.fulfilled
const transactionHash = '0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80'
const message = createMessage(recipientAccount, 1, transactionHash, homeContract.address)
expectEventInLogs(logs, 'UserRequestForSignature', { recipient: recipientAccount, value: toBN(1) })
expect(await homeContract.totalSpentPerDay(currentDay)).to.be.bignumber.equal('1')
expect(await homeContract.totalBurntCoins()).to.be.bignumber.equal('1')
const signature = await sign(authorities[0], message)
const homeContractBalance = toBN(await web3.eth.getBalance(homeContract.address))
homeContractBalance.should.be.bignumber.equal(ZERO)
expect(await validatorContract.requiredSignatures()).to.be.bignumber.equal('1')
const transactionHash = '0x1045bfe274b88120a6b1e5d01b5ec00ab5d01098346e90e7c7a3c9b8f0181c80'
const message = createMessage(recipientAccount, 1, transactionHash, homeContract.address)
const { logs: logsSubmitSignature } = await homeContract.submitSignature(signature, message, {
from: authorities[0]
}).should.be.fulfilled
const signature = await sign(authorities[0], message)
expect(await validatorContract.requiredSignatures()).to.be.bignumber.equal('1')
const { logs: logsSubmitSignature } = await homeContract.submitSignature(signature, message, {
from: authorities[0]
}).should.be.fulfilled
logsSubmitSignature.length.should.be.equal(2)
logsSubmitSignature[1].event.should.be.equal('CollectedSignatures')
})
logsSubmitSignature.length.should.be.equal(2)
logsSubmitSignature[1].event.should.be.equal('CollectedSignatures')
})
}
})
})

View File

@ -141,6 +141,20 @@ contract('ForeignBridge', async accounts => {
otherSideBridgeAddress
)
.should.be.rejectedWith(ERROR_MSG)
// not valid decimal shift
await foreignBridge.initialize(
validatorContract.address,
token.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
[homeDailyLimit, homeMaxPerTx],
owner,
'100',
otherSideBridgeAddress
).should.be.rejected
const { logs } = await foreignBridge.initialize(
validatorContract.address,
token.address,
@ -1458,83 +1472,85 @@ contract('ForeignBridge', async accounts => {
})
})
describe('#decimalShift', async () => {
const decimalShiftTwo = 2
it('Home to Foreign: withdraw works with decimalShift of 2', async () => {
const recipient = accounts[8]
const authoritiesFiveAccs = [accounts[1], accounts[2], accounts[3], accounts[4], accounts[5]]
const ownerOfValidators = accounts[0]
const validatorContractWith3Signatures = await BridgeValidators.new()
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
const erc20Token = await POA20.new('Some ERC20', 'RSZT', 16)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const foreignBridgeWithThreeSigs = await ForeignBridge.new()
for (const decimalShift of [2, -1]) {
it(`Home to Foreign: withdraw works with decimalShift of ${decimalShift}`, async () => {
const recipient = accounts[8]
const authoritiesFiveAccs = [accounts[1], accounts[2], accounts[3], accounts[4], accounts[5]]
const ownerOfValidators = accounts[0]
const validatorContractWith3Signatures = await BridgeValidators.new()
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
const erc20Token = await POA20.new('Some ERC20', 'RSZT', 16)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const foreignBridgeWithThreeSigs = await ForeignBridge.new()
await foreignBridgeWithThreeSigs.initialize(
validatorContractWith3Signatures.address,
erc20Token.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShiftTwo,
otherSideBridgeAddress
)
await erc20Token.transferOwnership(foreignBridgeWithThreeSigs.address)
await foreignBridgeWithThreeSigs.initialize(
validatorContractWith3Signatures.address,
erc20Token.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShift,
otherSideBridgeAddress
)
await erc20Token.transferOwnership(foreignBridgeWithThreeSigs.address)
const balanceBeforeRecipient = await erc20Token.balanceOf(recipient)
const txHash = '0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121'
const message = createMessage(recipient, valueOnHome, txHash, foreignBridgeWithThreeSigs.address)
const balanceBeforeRecipient = await erc20Token.balanceOf(recipient)
const txHash = '0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a25dbe7b8121'
const message = createMessage(recipient, valueOnHome, txHash, foreignBridgeWithThreeSigs.address)
// signature 1
const signature = await sign(authoritiesFiveAccs[0], message)
const vrs = signatureToVRS(signature)
// signature 1
const signature = await sign(authoritiesFiveAccs[0], message)
const vrs = signatureToVRS(signature)
// signature 2
const signature2 = await sign(authoritiesFiveAccs[1], message)
const vrs2 = signatureToVRS(signature2)
// signature 2
const signature2 = await sign(authoritiesFiveAccs[1], message)
const vrs2 = signatureToVRS(signature2)
// signature 3
const signature3 = await sign(authoritiesFiveAccs[2], message)
const vrs3 = signatureToVRS(signature3)
// signature 3
const signature3 = await sign(authoritiesFiveAccs[2], message)
const vrs3 = signatureToVRS(signature3)
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
const threeSignatures = packSignatures([vrs, vrs2, vrs3])
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(message, threeSignatures).should.be.fulfilled
logs[0].event.should.be.equal('RelayedMessage')
logs[0].args.recipient.should.be.equal(recipient)
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
true.should.be.equal(await foreignBridgeWithThreeSigs.relayedMessages(txHash))
const balanceAfterRecipient = await erc20Token.balanceOf(recipient)
balanceAfterRecipient.should.be.bignumber.equal(balanceBeforeRecipient.add(valueOnForeign))
const balanceAfterBridge = await erc20Token.balanceOf(foreignBridgeWithThreeSigs.address)
balanceAfterBridge.should.be.bignumber.equal(ZERO)
})
it('Foreign to Home: no impact in transferAndCall event signal for bridges oracles with a decimalShift of 2.', async () => {
const owner = accounts[3]
const user = accounts[4]
const value = halfEther
token = await POA20.new('POA ERC20 Foundation', 'POA20', 16, { from: owner })
const foreignBridge = await ForeignBridge.new()
await foreignBridge.initialize(
validatorContract.address,
token.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShiftTwo,
otherSideBridgeAddress
)
await token.mint(user, value, { from: owner }).should.be.fulfilled
expect(await token.balanceOf(user)).to.be.bignumber.equal(value)
await token.transferOwnership(foreignBridge.address, { from: owner })
const { logs } = await token.transferAndCall(foreignBridge.address, value, '0x', { from: user })
logs[0].event.should.be.equal('Transfer')
logs[0].args.value.should.be.bignumber.equal(value)
expect(await token.balanceOf(user)).to.be.bignumber.equal(ZERO)
})
const { logs } = await foreignBridgeWithThreeSigs.executeSignatures(message, threeSignatures).should.be
.fulfilled
logs[0].event.should.be.equal('RelayedMessage')
logs[0].args.recipient.should.be.equal(recipient)
logs[0].args.value.should.be.bignumber.equal(valueOnHome)
true.should.be.equal(await foreignBridgeWithThreeSigs.relayedMessages(txHash))
const balanceAfterRecipient = await erc20Token.balanceOf(recipient)
balanceAfterRecipient.should.be.bignumber.equal(balanceBeforeRecipient.add(valueOnForeign))
const balanceAfterBridge = await erc20Token.balanceOf(foreignBridgeWithThreeSigs.address)
balanceAfterBridge.should.be.bignumber.equal(ZERO)
})
it(`Foreign to Home: no impact in transferAndCall event signal for bridges oracles with a decimalShift of ${decimalShift}`, async () => {
const owner = accounts[3]
const user = accounts[4]
const value = halfEther
token = await POA20.new('POA ERC20 Foundation', 'POA20', 16, { from: owner })
const foreignBridge = await ForeignBridge.new()
await foreignBridge.initialize(
validatorContract.address,
token.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
[homeDailyLimit, homeMaxPerTx],
owner,
decimalShift,
otherSideBridgeAddress
)
await token.mint(user, value, { from: owner }).should.be.fulfilled
expect(await token.balanceOf(user)).to.be.bignumber.equal(value)
await token.transferOwnership(foreignBridge.address, { from: owner })
const { logs } = await token.transferAndCall(foreignBridge.address, value, '0x', { from: user })
logs[0].event.should.be.equal('Transfer')
logs[0].args.value.should.be.bignumber.equal(value)
expect(await token.balanceOf(user)).to.be.bignumber.equal(ZERO)
})
}
})
})

View File

@ -220,6 +220,18 @@ contract('HomeBridge', async accounts => {
decimalShiftZero
)
.should.be.rejectedWith(ERROR_MSG)
// not valid decimal shift
await homeContract.initialize(
validatorContract.address,
['3', '2', '1'],
gasPrice,
requireBlockConfirmations,
[foreignDailyLimit, foreignMaxPerTx],
owner,
'100'
).should.be.rejected
await homeContract.initialize(
validatorContract.address,
['3', '2', '1'],
@ -2495,99 +2507,100 @@ contract('HomeBridge', async accounts => {
})
})
describe('#decimalShift', async () => {
const decimalShiftTwo = 2
it('Foreign to Home: works with 5 validators and 3 required signatures with decimal shift 2', async () => {
const recipient = accounts[8]
const authoritiesFiveAccs = [accounts[1], accounts[2], accounts[3], accounts[4], accounts[5]]
const ownerOfValidators = accounts[0]
const validatorContractWith3Signatures = await BridgeValidators.new()
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
for (const decimalShift of [2, -1]) {
it(`Foreign to Home: works with 5 validators and 3 required signatures with decimal shift ${decimalShift}`, async () => {
const recipient = accounts[8]
const authoritiesFiveAccs = [accounts[1], accounts[2], accounts[3], accounts[4], accounts[5]]
const ownerOfValidators = accounts[0]
const validatorContractWith3Signatures = await BridgeValidators.new()
await validatorContractWith3Signatures.initialize(3, authoritiesFiveAccs, ownerOfValidators)
const homeBridgeWithThreeSigs = await HomeBridge.new()
await homeBridgeWithThreeSigs.initialize(
validatorContractWith3Signatures.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShiftTwo
)
const homeBridgeWithThreeSigs = await HomeBridge.new()
await homeBridgeWithThreeSigs.initialize(
validatorContractWith3Signatures.address,
[oneEther, halfEther, minPerTx],
gasPrice,
requireBlockConfirmations,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShift
)
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShiftTwo)
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'
const valueOnForeign = toBN('1000')
const valueOnHome = toBN(valueOnForeign * 10 ** decimalShift)
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'
await homeBridgeWithThreeSigs.sendTransaction({
from: recipient,
value: halfEther
}).should.be.fulfilled
await homeBridgeWithThreeSigs.sendTransaction({
from: recipient,
value: halfEther
}).should.be.fulfilled
const balanceBeforeRecipient = toBN(await web3.eth.getBalance(recipient))
const balanceBeforeRecipient = toBN(await web3.eth.getBalance(recipient))
const { logs } = await homeBridgeWithThreeSigs.executeAffirmation(recipient, valueOnForeign, transactionHash, {
from: authoritiesFiveAccs[0]
}).should.be.fulfilled
expectEventInLogs(logs, 'SignedForAffirmation', {
signer: authorities[0],
transactionHash
})
await homeBridgeWithThreeSigs.executeAffirmation(recipient, valueOnForeign, transactionHash, {
from: authoritiesFiveAccs[1]
}).should.be.fulfilled
const thirdSignature = await homeBridgeWithThreeSigs.executeAffirmation(
recipient,
valueOnForeign,
transactionHash,
{ from: authoritiesFiveAccs[2] }
).should.be.fulfilled
expectEventInLogs(thirdSignature.logs, 'AffirmationCompleted', {
recipient,
value: valueOnForeign,
transactionHash
})
const balanceAfterRecipient = toBN(await web3.eth.getBalance(recipient))
balanceAfterRecipient.should.be.bignumber.equal(balanceBeforeRecipient.add(valueOnHome))
})
it('Foreign to Home: test decimal shift 2, no impact on UserRequestForSignature value', async () => {
homeContract = await HomeBridge.new()
await homeContract.initialize(
validatorContract.address,
['3', '2', '1'],
gasPrice,
requireBlockConfirmations,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShiftTwo
)
const currentDay = await homeContract.getCurrentDay()
expect(await homeContract.totalSpentPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const { logs } = await homeContract.sendTransaction({
from: accounts[1],
value: 1
}).should.be.fulfilled
expect(await homeContract.totalSpentPerDay(currentDay)).to.be.bignumber.equal('1')
expectEventInLogs(logs, 'UserRequestForSignature', { recipient: accounts[1], value: toBN(1) })
await homeContract
.sendTransaction({
from: accounts[1],
value: 3
const { logs } = await homeBridgeWithThreeSigs.executeAffirmation(recipient, valueOnForeign, transactionHash, {
from: authoritiesFiveAccs[0]
}).should.be.fulfilled
expectEventInLogs(logs, 'SignedForAffirmation', {
signer: authorities[0],
transactionHash
})
.should.be.rejectedWith(ERROR_MSG)
await homeContract.setDailyLimit(4).should.be.fulfilled
await homeContract.sendTransaction({
from: accounts[1],
value: 1
}).should.be.fulfilled
await homeBridgeWithThreeSigs.executeAffirmation(recipient, valueOnForeign, transactionHash, {
from: authoritiesFiveAccs[1]
}).should.be.fulfilled
const thirdSignature = await homeBridgeWithThreeSigs.executeAffirmation(
recipient,
valueOnForeign,
transactionHash,
{ from: authoritiesFiveAccs[2] }
).should.be.fulfilled
expect(await homeContract.totalSpentPerDay(currentDay)).to.be.bignumber.equal('2')
})
expectEventInLogs(thirdSignature.logs, 'AffirmationCompleted', {
recipient,
value: valueOnForeign,
transactionHash
})
const balanceAfterRecipient = toBN(await web3.eth.getBalance(recipient))
balanceAfterRecipient.should.be.bignumber.equal(balanceBeforeRecipient.add(valueOnHome))
})
it(`Foreign to Home: test decimal shift ${decimalShift}, no impact on UserRequestForSignature value`, async () => {
homeContract = await HomeBridge.new()
await homeContract.initialize(
validatorContract.address,
['3', '2', '1'],
gasPrice,
requireBlockConfirmations,
[foreignDailyLimit, foreignMaxPerTx],
owner,
decimalShift
)
const currentDay = await homeContract.getCurrentDay()
expect(await homeContract.totalSpentPerDay(currentDay)).to.be.bignumber.equal(ZERO)
const { logs } = await homeContract.sendTransaction({
from: accounts[1],
value: 1
}).should.be.fulfilled
expect(await homeContract.totalSpentPerDay(currentDay)).to.be.bignumber.equal('1')
expectEventInLogs(logs, 'UserRequestForSignature', { recipient: accounts[1], value: toBN(1) })
await homeContract
.sendTransaction({
from: accounts[1],
value: 3
})
.should.be.rejectedWith(ERROR_MSG)
await homeContract.setDailyLimit(4).should.be.fulfilled
await homeContract.sendTransaction({
from: accounts[1],
value: 1
}).should.be.fulfilled
expect(await homeContract.totalSpentPerDay(currentDay)).to.be.bignumber.equal('2')
})
}
})
})