Skip to content

Commit

Permalink
Merge the develop branch to the master branch, preparation to v5.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
akolotov committed Jul 3, 2020
2 parents a90ce6c + 997c43e commit d67761d
Show file tree
Hide file tree
Showing 54 changed files with 4,101 additions and 209 deletions.
Expand Up @@ -3,7 +3,7 @@ pragma solidity 0.4.24;
import "../interfaces/IBlockReward.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";

contract BlockReward {
contract BlockRewardMock {
using SafeMath for uint256;

event BridgeTokenRewardAdded(uint256 amount, uint256 cumulativeAmount, address indexed bridge);
Expand Down
24 changes: 24 additions & 0 deletions contracts/mocks/BlockRewardWithoutSystem.sol
@@ -0,0 +1,24 @@
pragma solidity ^0.4.24;

import "../upgradeable_contracts/amb_erc20_to_native/BlockReward.sol";

contract BlockRewardWithoutSystem is BlockReward {
address public bridgeContractAddress;

modifier onlySystem {
_;
}

modifier onlyBridgeContract {
_;
}

function setBridgeContractAddress(address _addr) external {
bridgeContractAddress = _addr;
}

function bridgesAllowed() public view returns (address[bridgesAllowedLength]) {
// These values must be changed before deploy
return [address(bridgeContractAddress)];
}
}
4 changes: 2 additions & 2 deletions contracts/upgradeable_contracts/BaseERC677Bridge.sol
Expand Up @@ -8,7 +8,7 @@ import "./ERC677Storage.sol";
import "../libraries/Bytes.sol";

contract BaseERC677Bridge is BasicTokenBridge, ERC677Receiver, ERC677Storage {
function erc677token() public view returns (ERC677) {
function _erc677token() internal view returns (ERC677) {
return ERC677(addressStorage[ERC677_TOKEN]);
}

Expand All @@ -18,7 +18,7 @@ contract BaseERC677Bridge is BasicTokenBridge, ERC677Receiver, ERC677Storage {
}

function onTokenTransfer(address _from, uint256 _value, bytes _data) external returns (bool) {
ERC677 token = erc677token();
ERC677 token = _erc677token();
require(msg.sender == address(token));
require(withinLimit(_value));
setTotalSpentPerDay(getCurrentDay(), totalSpentPerDay(getCurrentDay()).add(_value));
Expand Down
147 changes: 147 additions & 0 deletions contracts/upgradeable_contracts/BaseRewardAddressList.sol
@@ -0,0 +1,147 @@
pragma solidity 0.4.24;

import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "../upgradeability/EternalStorage.sol";

/**
* @title BaseRewardAddressList
* @dev Implements the logic to store, add and remove reward account addresses. Works as a linked list.
*/
contract BaseRewardAddressList is EternalStorage {
using SafeMath for uint256;

address public constant F_ADDR = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF;
uint256 internal constant MAX_REWARD_ADDRESSES = 50;
bytes32 internal constant REWARD_ADDRESS_COUNT = 0xabc77c82721ced73eef2645facebe8c30249e6ac372cce6eb9d1fed31bd6648f; // keccak256(abi.encodePacked("rewardAddressCount"))

event RewardAddressAdded(address indexed addr);
event RewardAddressRemoved(address indexed addr);

/**
* @dev Retrieves all registered reward accounts.
* @return address list of the registered reward receivers.
*/
function rewardAddressList() external view returns (address[]) {
address[] memory list = new address[](rewardAddressCount());
uint256 counter = 0;
address nextAddr = getNextRewardAddress(F_ADDR);

while (nextAddr != F_ADDR) {
require(nextAddr != address(0));

list[counter] = nextAddr;
nextAddr = getNextRewardAddress(nextAddr);
counter++;
}

return list;
}

/**
* @dev Retrieves amount of registered reward accounts.
* @return length of reward addresses list.
*/
function rewardAddressCount() public view returns (uint256) {
return uintStorage[REWARD_ADDRESS_COUNT];
}

/**
* @dev Checks if specified address is included into the registered rewards receivers list.
* @param _addr address to verify.
* @return true, if specified address is associated with one of the registered reward accounts.
*/
function isRewardAddress(address _addr) public view returns (bool) {
return _addr != F_ADDR && getNextRewardAddress(_addr) != address(0);
}

/**
* @dev Retrieves next reward address in the linked list, or F_ADDR if given address is the last one.
* @param _address address of some reward account.
* @return address of the next reward receiver.
*/
function getNextRewardAddress(address _address) public view returns (address) {
return addressStorage[keccak256(abi.encodePacked("rewardAddressList", _address))];
}

/**
* @dev Internal function for adding a new reward address to the linked list.
* @param _addr new reward account.
*/
function _addRewardAddress(address _addr) internal {
require(_addr != address(0) && _addr != F_ADDR);
require(!isRewardAddress(_addr));

address nextAddr = getNextRewardAddress(F_ADDR);

require(nextAddr != address(0));

_setNextRewardAddress(_addr, nextAddr);
_setNextRewardAddress(F_ADDR, _addr);
_setRewardAddressCount(rewardAddressCount().add(1));
}

/**
* @dev Internal function for removing existing reward address from the linked list.
* @param _addr old reward account which should be removed.
*/
function _removeRewardAddress(address _addr) internal {
require(isRewardAddress(_addr));
address nextAddr = getNextRewardAddress(_addr);
address index = F_ADDR;
address next = getNextRewardAddress(index);

while (next != _addr) {
require(next != address(0));
index = next;
next = getNextRewardAddress(index);
require(next != F_ADDR);
}

_setNextRewardAddress(index, nextAddr);
delete addressStorage[keccak256(abi.encodePacked("rewardAddressList", _addr))];
_setRewardAddressCount(rewardAddressCount().sub(1));
}

/**
* @dev Internal function for initializing linked list with the array of the initial reward addresses.
* @param _rewardAddresses initial reward addresses list, should be non-empty.
*/
function _setRewardAddressList(address[] _rewardAddresses) internal {
require(_rewardAddresses.length > 0);

_setNextRewardAddress(F_ADDR, _rewardAddresses[0]);

for (uint256 i = 0; i < _rewardAddresses.length; i++) {
require(_rewardAddresses[i] != address(0) && _rewardAddresses[i] != F_ADDR);
require(!isRewardAddress(_rewardAddresses[i]));

if (i == _rewardAddresses.length - 1) {
_setNextRewardAddress(_rewardAddresses[i], F_ADDR);
} else {
_setNextRewardAddress(_rewardAddresses[i], _rewardAddresses[i + 1]);
}

emit RewardAddressAdded(_rewardAddresses[i]);
}

_setRewardAddressCount(_rewardAddresses.length);
}

/**
* @dev Internal function for updating the length of the reward accounts list.
* @param _rewardAddressCount new linked list length.
*/
function _setRewardAddressCount(uint256 _rewardAddressCount) internal {
require(_rewardAddressCount <= MAX_REWARD_ADDRESSES);
uintStorage[REWARD_ADDRESS_COUNT] = _rewardAddressCount;
}

/**
* @dev Internal function for updating the pointer to the next reward receiver.
* @param _prevAddr address of some reward receiver.
* @param _addr address of the next receiver to which _prevAddr should point to.
*/
function _setNextRewardAddress(address _prevAddr, address _addr) internal {
addressStorage[keccak256(abi.encodePacked("rewardAddressList", _prevAddr))] = _addr;
}
}
17 changes: 14 additions & 3 deletions contracts/upgradeable_contracts/BasicBridge.sol
Expand Up @@ -15,10 +15,12 @@ contract BasicBridge is InitializableBridge, Validatable, Ownable, Upgradeable,
bytes32 internal constant GAS_PRICE = 0x55b3774520b5993024893d303890baa4e84b1244a43c60034d1ced2d3cf2b04b; // keccak256(abi.encodePacked("gasPrice"))
bytes32 internal constant REQUIRED_BLOCK_CONFIRMATIONS = 0x916daedf6915000ff68ced2f0b6773fe6f2582237f92c3c95bb4d79407230071; // keccak256(abi.encodePacked("requiredBlockConfirmations"))

/**
* @dev Public setter for fallback gas price value. Only bridge owner can call this method.
* @param _gasPrice new value for the gas price.
*/
function setGasPrice(uint256 _gasPrice) external onlyOwner {
require(_gasPrice > 0);
uintStorage[GAS_PRICE] = _gasPrice;
emit GasPriceChanged(_gasPrice);
_setGasPrice(_gasPrice);
}

function gasPrice() external view returns (uint256) {
Expand All @@ -38,4 +40,13 @@ contract BasicBridge is InitializableBridge, Validatable, Ownable, Upgradeable,
function claimTokens(address _token, address _to) public onlyIfUpgradeabilityOwner validAddress(_to) {
claimValues(_token, _to);
}

/**
* @dev Internal function for updating fallback gas price value.
* @param _gasPrice new value for the gas price, zero gas price is allowed.
*/
function _setGasPrice(uint256 _gasPrice) internal {
uintStorage[GAS_PRICE] = _gasPrice;
emit GasPriceChanged(_gasPrice);
}
}
9 changes: 9 additions & 0 deletions contracts/upgradeable_contracts/BasicForeignBridge.sol
Expand Up @@ -39,6 +39,15 @@ contract BasicForeignBridge is EternalStorage, Validatable, BasicBridge, BasicTo
}
}

/**
* @dev Internal function for updating fallback gas price value.
* @param _gasPrice new value for the gas price, zero gas price is not allowed.
*/
function _setGasPrice(uint256 _gasPrice) internal {
require(_gasPrice > 0);
super._setGasPrice(_gasPrice);
}

/* solcov ignore next */
function onExecuteMessage(address, uint256, bytes32) internal returns (bool);

Expand Down
4 changes: 4 additions & 0 deletions contracts/upgradeable_contracts/ERC677Bridge.sol
Expand Up @@ -4,6 +4,10 @@ import "./BaseERC677Bridge.sol";
import "./OtherSideBridgeStorage.sol";

contract ERC677Bridge is BaseERC677Bridge, OtherSideBridgeStorage {
function erc677token() public view returns (ERC677) {
return _erc677token();
}

function bridgeSpecificActionsOnTokenTransfer(
ERC677, /*_token*/
address _from,
Expand Down
8 changes: 8 additions & 0 deletions contracts/upgradeable_contracts/RewardableMediator.sol
Expand Up @@ -19,6 +19,14 @@ contract RewardableMediator is Ownable {
* @param _feeManager the address of the fee manager contract.
*/
function setFeeManagerContract(address _feeManager) external onlyOwner {
_setFeeManagerContract(_feeManager);
}

/**
* @dev Internal function for enabling new / disabling fee manage contract.
* @param _feeManager the address of the fee manager contract.
*/
function _setFeeManagerContract(address _feeManager) internal {
require(_feeManager == address(0) || AddressUtils.isContract(_feeManager));
addressStorage[FEE_MANAGER_CONTRACT] = _feeManager;
}
Expand Down
@@ -0,0 +1,86 @@
pragma solidity 0.4.24;

import "../Initializable.sol";
import "../Upgradeable.sol";
import "../Claimable.sol";
import "../VersionableBridge.sol";
import "../TokenBridgeMediator.sol";

/**
* @title BasicAMBErc20ToNative
* @dev Common mediator functionality for erc20-to-native bridge intended to work on top of AMB bridge.
*/
contract BasicAMBErc20ToNative is Initializable, Upgradeable, Claimable, VersionableBridge, TokenBridgeMediator {
/**
* @dev Stores the initial parameters of the mediator.
* @param _bridgeContract the address of the AMB bridge contract.
* @param _mediatorContract the address of the mediator contract on the other network.
* @param _dailyLimitMaxPerTxMinPerTxArray array with limit values for the assets to be bridged to the other network.
* [ 0 = dailyLimit, 1 = maxPerTx, 2 = minPerTx ]
* @param _executionDailyLimitExecutionMaxPerTxArray array with limit values for the assets bridged from the other network.
* [ 0 = executionDailyLimit, 1 = executionMaxPerTx ]
* @param _requestGasLimit the gas limit for the message execution.
* @param _decimalShift number of decimals shift required to adjust the amount of tokens bridged.
* @param _owner address of the owner of the mediator contract
*/
function _initialize(
address _bridgeContract,
address _mediatorContract,
uint256[] _dailyLimitMaxPerTxMinPerTxArray,
uint256[] _executionDailyLimitExecutionMaxPerTxArray,
uint256 _requestGasLimit,
uint256 _decimalShift,
address _owner
) internal {
require(!isInitialized());
require(
_dailyLimitMaxPerTxMinPerTxArray[2] > 0 && // minPerTx > 0
_dailyLimitMaxPerTxMinPerTxArray[1] > _dailyLimitMaxPerTxMinPerTxArray[2] && // maxPerTx > minPerTx
_dailyLimitMaxPerTxMinPerTxArray[0] > _dailyLimitMaxPerTxMinPerTxArray[1] // dailyLimit > maxPerTx
);
require(_executionDailyLimitExecutionMaxPerTxArray[1] < _executionDailyLimitExecutionMaxPerTxArray[0]); // foreignMaxPerTx < foreignDailyLimit
require(_owner != address(0));

_setBridgeContract(_bridgeContract);
_setMediatorContractOnOtherSide(_mediatorContract);
_setRequestGasLimit(_requestGasLimit);
uintStorage[DAILY_LIMIT] = _dailyLimitMaxPerTxMinPerTxArray[0];
uintStorage[MAX_PER_TX] = _dailyLimitMaxPerTxMinPerTxArray[1];
uintStorage[MIN_PER_TX] = _dailyLimitMaxPerTxMinPerTxArray[2];
uintStorage[EXECUTION_DAILY_LIMIT] = _executionDailyLimitExecutionMaxPerTxArray[0];
uintStorage[EXECUTION_MAX_PER_TX] = _executionDailyLimitExecutionMaxPerTxArray[1];
uintStorage[DECIMAL_SHIFT] = _decimalShift;
setOwner(_owner);

emit DailyLimitChanged(_dailyLimitMaxPerTxMinPerTxArray[0]);
emit ExecutionDailyLimitChanged(_executionDailyLimitExecutionMaxPerTxArray[0]);
}

/**
* @dev Tells the bridge interface version that this contract supports.
* @return major value of the version
* @return minor value of the version
* @return patch value of the version
*/
function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) {
return (1, 0, 0);
}

/**
* @dev Tells the bridge mode that this contract supports.
* @return _data 4 bytes representing the bridge mode
*/
function getBridgeMode() external pure returns (bytes4 _data) {
return 0xe177c00f; // bytes4(keccak256(abi.encodePacked("erc-to-native-amb")))
}

/**
* @dev Execute the action to be performed when the bridge tokens are out of execution limits.
*/
function executeActionOnBridgedTokensOutOfLimit(
address, /* _recipient */
uint256 /* _value */
) internal {
revert();
}
}

0 comments on commit d67761d

Please sign in to comment.