Contract Address Details

0x3B09067f5FbC8087391f6997ccd83337195eaC05

HomeAMBErc677ToErc677 Last Balance Update: Block #11343199
Created by 0xbf3d–442b53 at 0xa318–6715ae

Balance

0 xDAI

(@ /xDAI)

Fetching tokens...

Contract name:
HomeAMBErc677ToErc677




Optimization enabled
false
Compiler version
v0.4.24+commit.e67f0147




EVM Version
default

Contract source code

/**
* Submitted for verification at blockscout.com on 2020-06-19 12:14:57.176173Z
*/
// File: contracts/interfaces/IAMB.sol
pragma solidity 0.4.24;
interface IAMB {
function messageSender() external view returns (address);
function maxGasPerTx() external view returns (uint256);
function transactionHash() external view returns (bytes32);
function messageId() external view returns (bytes32);
function messageSourceChainId() external view returns (bytes32);
function messageCallStatus(bytes32 _messageId) external view returns (bool);
function failedMessageDataHash(bytes32 _messageId) external view returns (bytes32);
function failedMessageReceiver(bytes32 _messageId) external view returns (address);
function failedMessageSender(bytes32 _messageId) external view returns (address);
function requireToPassMessage(address _contract, bytes _data, uint256 _gas) external returns (bytes32);
}
// File: contracts/upgradeability/EternalStorage.sol
pragma solidity 0.4.24;
/**
* @title EternalStorage
* @dev This contract holds all the necessary state variables to carry out the storage of any contract.
*/
contract EternalStorage {
mapping(bytes32 => uint256) internal uintStorage;
mapping(bytes32 => string) internal stringStorage;
mapping(bytes32 => address) internal addressStorage;
mapping(bytes32 => bytes) internal bytesStorage;
mapping(bytes32 => bool) internal boolStorage;
mapping(bytes32 => int256) internal intStorage;
}
// File: contracts/interfaces/IUpgradeabilityOwnerStorage.sol
pragma solidity 0.4.24;
interface IUpgradeabilityOwnerStorage {
function upgradeabilityOwner() external view returns (address);
}
// File: contracts/upgradeable_contracts/Ownable.sol
pragma solidity 0.4.24;
/**
* @title Ownable
* @dev This contract has an owner address providing basic authorization control
*/
contract Ownable is EternalStorage {
bytes4 internal constant UPGRADEABILITY_OWNER = 0x6fde8202; // upgradeabilityOwner()
/**
* @dev Event to show ownership has been transferred
* @param previousOwner representing the address of the previous owner
* @param newOwner representing the address of the new owner
*/
event OwnershipTransferred(address previousOwner, address newOwner);
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner());
/* solcov ignore next */
_;
}
/**
* @dev Throws if called by any account other than contract itself or owner.
*/
modifier onlyRelevantSender() {
// proxy owner if used through proxy, address(0) otherwise
require(
!address(this).call(abi.encodeWithSelector(UPGRADEABILITY_OWNER)) || // covers usage without calling through storage proxy
msg.sender == IUpgradeabilityOwnerStorage(this).upgradeabilityOwner() || // covers usage through regular proxy calls
msg.sender == address(this) // covers calls through upgradeAndCall proxy method
);
/* solcov ignore next */
_;
}
bytes32 internal constant OWNER = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0; // keccak256(abi.encodePacked("owner"))
/**
* @dev Tells the address of the owner
* @return the address of the owner
*/
function owner() public view returns (address) {
return addressStorage[OWNER];
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner the address to transfer ownership to.
*/
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0));
setOwner(newOwner);
}
/**
* @dev Sets a new owner address
*/
function setOwner(address newOwner) internal {
emit OwnershipTransferred(owner(), newOwner);
addressStorage[OWNER] = newOwner;
}
}
// File: contracts/upgradeable_contracts/Initializable.sol
pragma solidity 0.4.24;
contract Initializable is EternalStorage {
bytes32 internal constant INITIALIZED = 0x0a6f646cd611241d8073675e00d1a1ff700fbf1b53fcf473de56d1e6e4b714ba; // keccak256(abi.encodePacked("isInitialized"))
function setInitialize() internal {
boolStorage[INITIALIZED] = true;
}
function isInitialized() public view returns (bool) {
return boolStorage[INITIALIZED];
}
}
// File: openzeppelin-solidity/contracts/AddressUtils.sol
pragma solidity ^0.4.24;
/**
* Utility library of inline functions on addresses
*/
library AddressUtils {
/**
* Returns whether the target address is a contract
* @dev This function will return false if invoked during the constructor of a contract,
* as the code is not actually created until after the constructor finishes.
* @param _addr address to check
* @return whether the target address is a contract
*/
function isContract(address _addr) internal view returns (bool) {
uint256 size;
// XXX Currently there is no better way to check if there is a contract in an address
// than to check the size of the code at that address.
// See https://ethereum.stackexchange.com/a/14016/36603
// for more details about how this works.
// TODO Check this again before the Serenity release, because all addresses will be
// contracts then.
// solium-disable-next-line security/no-inline-assembly
assembly { size := extcodesize(_addr) }
return size > 0;
}
}
// File: openzeppelin-solidity/contracts/math/SafeMath.sol
pragma solidity ^0.4.24;
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
// Gas optimization: this is cheaper than asserting 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (_a == 0) {
return 0;
}
c = _a * _b;
assert(c / _a == _b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
// assert(_b > 0); // Solidity automatically throws when dividing by 0
// uint256 c = _a / _b;
// assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold
return _a / _b;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
assert(_b <= _a);
return _a - _b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
c = _a + _b;
assert(c >= _a);
return c;
}
}
// File: contracts/upgradeable_contracts/BasicTokenBridge.sol
pragma solidity 0.4.24;
contract BasicTokenBridge is EternalStorage, Ownable {
using SafeMath for uint256;
event DailyLimitChanged(uint256 newLimit);
event ExecutionDailyLimitChanged(uint256 newLimit);
bytes32 internal constant MIN_PER_TX = 0xbbb088c505d18e049d114c7c91f11724e69c55ad6c5397e2b929e68b41fa05d1; // keccak256(abi.encodePacked("minPerTx"))
bytes32 internal constant MAX_PER_TX = 0x0f8803acad17c63ee38bf2de71e1888bc7a079a6f73658e274b08018bea4e29c; // keccak256(abi.encodePacked("maxPerTx"))
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))];
}
function totalExecutedPerDay(uint256 _day) public view returns (uint256) {
return uintStorage[keccak256(abi.encodePacked("totalExecutedPerDay", _day))];
}
function dailyLimit() public view returns (uint256) {
return uintStorage[DAILY_LIMIT];
}
function executionDailyLimit() public view returns (uint256) {
return uintStorage[EXECUTION_DAILY_LIMIT];
}
function maxPerTx() public view returns (uint256) {
return uintStorage[MAX_PER_TX];
}
function executionMaxPerTx() public view returns (uint256) {
return uintStorage[EXECUTION_MAX_PER_TX];
}
function minPerTx() public view returns (uint256) {
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();
}
function withinExecutionLimit(uint256 _amount) public view returns (bool) {
uint256 nextLimit = totalExecutedPerDay(getCurrentDay()).add(_amount);
return executionDailyLimit() >= nextLimit && _amount <= executionMaxPerTx();
}
function getCurrentDay() public view returns (uint256) {
// solhint-disable-next-line not-rely-on-time
return now / 1 days;
}
function setTotalSpentPerDay(uint256 _day, uint256 _value) internal {
uintStorage[keccak256(abi.encodePacked("totalSpentPerDay", _day))] = _value;
}
function setTotalExecutedPerDay(uint256 _day, uint256 _value) internal {
uintStorage[keccak256(abi.encodePacked("totalExecutedPerDay", _day))] = _value;
}
function setDailyLimit(uint256 _dailyLimit) external onlyOwner {
require(_dailyLimit > maxPerTx() || _dailyLimit == 0);
uintStorage[DAILY_LIMIT] = _dailyLimit;
emit DailyLimitChanged(_dailyLimit);
}
function setExecutionDailyLimit(uint256 _dailyLimit) external onlyOwner {
require(_dailyLimit > executionMaxPerTx() || _dailyLimit == 0);
uintStorage[EXECUTION_DAILY_LIMIT] = _dailyLimit;
emit ExecutionDailyLimitChanged(_dailyLimit);
}
function setExecutionMaxPerTx(uint256 _maxPerTx) external onlyOwner {
require(_maxPerTx < executionDailyLimit());
uintStorage[EXECUTION_MAX_PER_TX] = _maxPerTx;
}
function setMaxPerTx(uint256 _maxPerTx) external onlyOwner {
require(_maxPerTx == 0 || (_maxPerTx > minPerTx() && _maxPerTx < dailyLimit()));
uintStorage[MAX_PER_TX] = _maxPerTx;
}
function setMinPerTx(uint256 _minPerTx) external onlyOwner {
require(_minPerTx > 0 && _minPerTx < dailyLimit() && _minPerTx < maxPerTx());
uintStorage[MIN_PER_TX] = _minPerTx;
}
}
// File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol
pragma solidity ^0.4.24;
/**
* @title ERC20Basic
* @dev Simpler version of ERC20 interface
* See https://github.com/ethereum/EIPs/issues/179
*/
contract ERC20Basic {
function totalSupply() public view returns (uint256);
function balanceOf(address _who) public view returns (uint256);
function transfer(address _to, uint256 _value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
// File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol
pragma solidity ^0.4.24;
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 is ERC20Basic {
function allowance(address _owner, address _spender)
public view returns (uint256);
function transferFrom(address _from, address _to, uint256 _value)
public returns (bool);
function approve(address _spender, uint256 _value) public returns (bool);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
// File: contracts/interfaces/ERC677.sol
pragma solidity 0.4.24;
contract ERC677 is ERC20 {
event Transfer(address indexed from, address indexed to, uint256 value, bytes data);
function transferAndCall(address, uint256, bytes) external returns (bool);
function increaseAllowance(address spender, uint256 addedValue) public returns (bool);
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool);
}
// File: contracts/interfaces/ERC677Receiver.sol
pragma solidity 0.4.24;
contract ERC677Receiver {
function onTokenTransfer(address _from, uint256 _value, bytes _data) external returns (bool);
}
// File: contracts/upgradeable_contracts/ERC677Storage.sol
pragma solidity 0.4.24;
contract ERC677Storage {
bytes32 internal constant ERC677_TOKEN = 0xa8b0ade3e2b734f043ce298aca4cc8d19d74270223f34531d0988b7d00cba21d; // keccak256(abi.encodePacked("erc677token"))
}
// File: contracts/libraries/Bytes.sol
pragma solidity 0.4.24;
/**
* @title Bytes
* @dev Helper methods to transform bytes to other solidity types.
*/
library Bytes {
/**
* @dev Converts bytes array to bytes32.
* Truncates bytes array if its size is more than 32 bytes.
* NOTE: This function does not perform any checks on the received parameter.
* Make sure that the _bytes argument has a correct length, not less than 32 bytes.
* A case when _bytes has length less than 32 will lead to the undefined behaviour,
* since assembly will read data from memory that is not related to the _bytes argument.
* @param _bytes to be converted to bytes32 type
* @return bytes32 type of the firsts 32 bytes array in parameter.
*/
function bytesToBytes32(bytes _bytes) internal pure returns (bytes32 result) {
assembly {
result := mload(add(_bytes, 32))
}
}
/**
* @dev Truncate bytes array if its size is more than 20 bytes.
* NOTE: Similar to the bytesToBytes32 function, make sure that _bytes is not shorter than 20 bytes.
* @param _bytes to be converted to address type
* @return address included in the firsts 20 bytes of the bytes array in parameter.
*/
function bytesToAddress(bytes _bytes) internal pure returns (address addr) {
assembly {
addr := mload(add(_bytes, 20))
}
}
}
// File: contracts/upgradeable_contracts/BaseERC677Bridge.sol
pragma solidity 0.4.24;
contract BaseERC677Bridge is BasicTokenBridge, ERC677Receiver, ERC677Storage {
function erc677token() public view returns (ERC677) {
return ERC677(addressStorage[ERC677_TOKEN]);
}
function setErc677token(address _token) internal {
require(AddressUtils.isContract(_token));
addressStorage[ERC677_TOKEN] = _token;
}
function onTokenTransfer(address _from, uint256 _value, bytes _data) external returns (bool) {
ERC677 token = erc677token();
require(msg.sender == address(token));
require(withinLimit(_value));
setTotalSpentPerDay(getCurrentDay(), totalSpentPerDay(getCurrentDay()).add(_value));
bridgeSpecificActionsOnTokenTransfer(token, _from, _value, _data);
return true;
}
function chooseReceiver(address _from, bytes _data) internal view returns (address recipient) {
recipient = _from;
if (_data.length > 0) {
require(_data.length == 20);
recipient = Bytes.bytesToAddress(_data);
require(recipient != address(0));
require(recipient != bridgeContractOnOtherSide());
}
}
/* solcov ignore next */
function bridgeSpecificActionsOnTokenTransfer(ERC677 _token, address _from, uint256 _value, bytes _data) internal;
/* solcov ignore next */
function bridgeContractOnOtherSide() internal view returns (address);
}
// File: contracts/upgradeable_contracts/BaseOverdrawManagement.sol
pragma solidity 0.4.24;
contract BaseOverdrawManagement is EternalStorage {
event AmountLimitExceeded(address recipient, uint256 value, bytes32 transactionHash);
event AssetAboveLimitsFixed(bytes32 indexed transactionHash, uint256 value, uint256 remaining);
bytes32 internal constant OUT_OF_LIMIT_AMOUNT = 0x145286dc85799b6fb9fe322391ba2d95683077b2adf34dd576dedc437e537ba7; // keccak256(abi.encodePacked("outOfLimitAmount"))
function outOfLimitAmount() public view returns (uint256) {
return uintStorage[OUT_OF_LIMIT_AMOUNT];
}
function fixedAssets(bytes32 _txHash) public view returns (bool) {
return boolStorage[keccak256(abi.encodePacked("fixedAssets", _txHash))];
}
function setOutOfLimitAmount(uint256 _value) internal {
uintStorage[OUT_OF_LIMIT_AMOUNT] = _value;
}
function txAboveLimits(bytes32 _txHash) internal view returns (address recipient, uint256 value) {
recipient = addressStorage[keccak256(abi.encodePacked("txOutOfLimitRecipient", _txHash))];
value = uintStorage[keccak256(abi.encodePacked("txOutOfLimitValue", _txHash))];
}
function setTxAboveLimits(address _recipient, uint256 _value, bytes32 _txHash) internal {
addressStorage[keccak256(abi.encodePacked("txOutOfLimitRecipient", _txHash))] = _recipient;
setTxAboveLimitsValue(_value, _txHash);
}
function setTxAboveLimitsValue(uint256 _value, bytes32 _txHash) internal {
uintStorage[keccak256(abi.encodePacked("txOutOfLimitValue", _txHash))] = _value;
}
function setFixedAssets(bytes32 _txHash) internal {
boolStorage[keccak256(abi.encodePacked("fixedAssets", _txHash))] = true;
}
/* solcov ignore next */
function fixAssetsAboveLimits(bytes32 txHash, bool unlockOnForeign, uint256 valueToUnlock) external;
}
// File: contracts/upgradeable_contracts/ReentrancyGuard.sol
pragma solidity 0.4.24;
contract ReentrancyGuard is EternalStorage {
bytes32 internal constant LOCK = 0x6168652c307c1e813ca11cfb3a601f1cf3b22452021a5052d8b05f1f1f8a3e92; // keccak256(abi.encodePacked("lock"))
function lock() internal returns (bool) {
return boolStorage[LOCK];
}
function setLock(bool _lock) internal {
boolStorage[LOCK] = _lock;
}
}
// File: contracts/upgradeable_contracts/Upgradeable.sol
pragma solidity 0.4.24;
contract Upgradeable {
// Avoid using onlyUpgradeabilityOwner name to prevent issues with implementation from proxy contract
modifier onlyIfUpgradeabilityOwner() {
require(msg.sender == IUpgradeabilityOwnerStorage(this).upgradeabilityOwner());
/* solcov ignore next */
_;
}
}
// File: contracts/upgradeable_contracts/Sacrifice.sol
pragma solidity 0.4.24;
contract Sacrifice {
constructor(address _recipient) public payable {
selfdestruct(_recipient);
}
}
// File: contracts/libraries/Address.sol
pragma solidity 0.4.24;
/**
* @title Address
* @dev Helper methods for Address type.
*/
library Address {
/**
* @dev Try to send native tokens to the address. If it fails, it will force the transfer by creating a selfdestruct contract
* @param _receiver address that will receive the native tokens
* @param _value the amount of native tokens to send
*/
function safeSendValue(address _receiver, uint256 _value) internal {
if (!_receiver.send(_value)) {
(new Sacrifice).value(_value)(_receiver);
}
}
}
// File: contracts/upgradeable_contracts/Claimable.sol
pragma solidity 0.4.24;
contract Claimable {
bytes4 internal constant TRANSFER = 0xa9059cbb; // transfer(address,uint256)
modifier validAddress(address _to) {
require(_to != address(0));
/* solcov ignore next */
_;
}
function claimValues(address _token, address _to) internal {
if (_token == address(0)) {
claimNativeCoins(_to);
} else {
claimErc20Tokens(_token, _to);
}
}
function claimNativeCoins(address _to) internal {
uint256 value = address(this).balance;
Address.safeSendValue(_to, value);
}
function claimErc20Tokens(address _token, address _to) internal {
ERC20Basic token = ERC20Basic(_token);
uint256 balance = token.balanceOf(this);
safeTransfer(_token, _to, balance);
}
function safeTransfer(address _token, address _to, uint256 _value) internal {
bytes memory returnData;
bool returnDataResult;
bytes memory callData = abi.encodeWithSelector(TRANSFER, _to, _value);
assembly {
let result := call(gas, _token, 0x0, add(callData, 0x20), mload(callData), 0, 32)
returnData := mload(0)
returnDataResult := mload(0)
switch result
case 0 {
revert(0, 0)
}
}
// Return data is optional
if (returnData.length > 0) {
require(returnDataResult);
}
}
}
// File: contracts/upgradeable_contracts/VersionableBridge.sol
pragma solidity 0.4.24;
contract VersionableBridge {
function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) {
return (5, 0, 0);
}
/* solcov ignore next */
function getBridgeMode() external pure returns (bytes4);
}
// File: contracts/upgradeable_contracts/BasicAMBMediator.sol
pragma solidity 0.4.24;
/**
* @title BasicAMBMediator
* @dev Basic storage and methods needed by mediators to interact with AMB bridge.
*/
contract BasicAMBMediator is Ownable {
bytes32 internal constant BRIDGE_CONTRACT = 0x811bbb11e8899da471f0e69a3ed55090fc90215227fc5fb1cb0d6e962ea7b74f; // keccak256(abi.encodePacked("bridgeContract"))
bytes32 internal constant MEDIATOR_CONTRACT = 0x98aa806e31e94a687a31c65769cb99670064dd7f5a87526da075c5fb4eab9880; // keccak256(abi.encodePacked("mediatorContract"))
bytes32 internal constant REQUEST_GAS_LIMIT = 0x2dfd6c9f781bb6bbb5369c114e949b69ebb440ef3d4dd6b2836225eb1dc3a2be; // keccak256(abi.encodePacked("requestGasLimit"))
/**
* @dev Sets the AMB bridge contract address. Only the owner can call this method.
* @param _bridgeContract the address of the bridge contract.
*/
function setBridgeContract(address _bridgeContract) external onlyOwner {
_setBridgeContract(_bridgeContract);
}
/**
* @dev Sets the mediator contract address from the other network. Only the owner can call this method.
* @param _mediatorContract the address of the mediator contract.
*/
function setMediatorContractOnOtherSide(address _mediatorContract) external onlyOwner {
_setMediatorContractOnOtherSide(_mediatorContract);
}
/**
* @dev Sets the gas limit to be used in the message execution by the AMB bridge on the other network.
* This value can't exceed the parameter maxGasPerTx defined on the AMB bridge.
* Only the owner can call this method.
* @param _requestGasLimit the gas limit for the message execution.
*/
function setRequestGasLimit(uint256 _requestGasLimit) external onlyOwner {
_setRequestGasLimit(_requestGasLimit);
}
/**
* @dev Get the AMB interface for the bridge contract address
* @return AMB interface for the bridge contract address
*/
function bridgeContract() public view returns (IAMB) {
return IAMB(addressStorage[BRIDGE_CONTRACT]);
}
/**
* @dev Tells the mediator contract address from the other network.
* @return the address of the mediator contract.
*/
function mediatorContractOnOtherSide() public view returns (address) {
return addressStorage[MEDIATOR_CONTRACT];
}
/**
* @dev Tells the gas limit to be used in the message execution by the AMB bridge on the other network.
* @return the gas limit for the message execution.
*/
function requestGasLimit() public view returns (uint256) {
return uintStorage[REQUEST_GAS_LIMIT];
}
/**
* @dev Stores a valid AMB bridge contract address.
* @param _bridgeContract the address of the bridge contract.
*/
function _setBridgeContract(address _bridgeContract) internal {
require(AddressUtils.isContract(_bridgeContract));
addressStorage[BRIDGE_CONTRACT] = _bridgeContract;
}
/**
* @dev Stores the mediator contract address from the other network.
* @param _mediatorContract the address of the mediator contract.
*/
function _setMediatorContractOnOtherSide(address _mediatorContract) internal {
addressStorage[MEDIATOR_CONTRACT] = _mediatorContract;
}
/**
* @dev Stores the gas limit to be used in the message execution by the AMB bridge on the other network.
* @param _requestGasLimit the gas limit for the message execution.
*/
function _setRequestGasLimit(uint256 _requestGasLimit) internal {
require(_requestGasLimit <= maxGasPerTx());
uintStorage[REQUEST_GAS_LIMIT] = _requestGasLimit;
}
/**
* @dev Tells the address that generated the message on the other network that is currently being executed by
* the AMB bridge.
* @return the address of the message sender.
*/
function messageSender() internal view returns (address) {
return bridgeContract().messageSender();
}
/**
* @dev Tells the id of the message originated on the other network.
* @return the id of the message originated on the other network.
*/
function messageId() internal view returns (bytes32) {
return bridgeContract().messageId();
}
/**
* @dev Tells the maximum gas limit that a message can use on its execution by the AMB bridge on the other network.
* @return the maximum gas limit value.
*/
function maxGasPerTx() internal view returns (uint256) {
return bridgeContract().maxGasPerTx();
}
}
// File: contracts/upgradeable_contracts/TokenBridgeMediator.sol
pragma solidity 0.4.24;
/**
* @title TokenBridgeMediator
* @dev Common mediator functionality to handle operations related to token bridge messages sent to AMB bridge.
*/
contract TokenBridgeMediator is BasicAMBMediator, BasicTokenBridge {
event FailedMessageFixed(bytes32 indexed messageId, address recipient, uint256 value);
event TokensBridged(address indexed recipient, uint256 value, bytes32 indexed messageId);
/**
* @dev Stores the value of a message sent to the AMB bridge.
* @param _messageId of the message sent to the bridge.
* @param _value amount of tokens bridged.
*/
function setMessageValue(bytes32 _messageId, uint256 _value) internal {
uintStorage[keccak256(abi.encodePacked("messageValue", _messageId))] = _value;
}
/**
* @dev Tells the amount of tokens of a message sent to the AMB bridge.
* @return value representing amount of tokens.
*/
function messageValue(bytes32 _messageId) internal view returns (uint256) {
return uintStorage[keccak256(abi.encodePacked("messageValue", _messageId))];
}
/**
* @dev Stores the receiver of a message sent to the AMB bridge.
* @param _messageId of the message sent to the bridge.
* @param _recipient receiver of the tokens bridged.
*/
function setMessageRecipient(bytes32 _messageId, address _recipient) internal {
addressStorage[keccak256(abi.encodePacked("messageRecipient", _messageId))] = _recipient;
}
/**
* @dev Tells the receiver of a message sent to the AMB bridge.
* @return address of the receiver.
*/
function messageRecipient(bytes32 _messageId) internal view returns (address) {
return addressStorage[keccak256(abi.encodePacked("messageRecipient", _messageId))];
}
/**
* @dev Sets that the message sent to the AMB bridge has been fixed.
* @param _messageId of the message sent to the bridge.
*/
function setMessageFixed(bytes32 _messageId) internal {
boolStorage[keccak256(abi.encodePacked("messageFixed", _messageId))] = true;
}
/**
* @dev Tells if a message sent to the AMB bridge has been fixed.
* @return bool indicating the status of the message.
*/
function messageFixed(bytes32 _messageId) public view returns (bool) {
return boolStorage[keccak256(abi.encodePacked("messageFixed", _messageId))];
}
/**
* @dev Call AMB bridge to require the invocation of handleBridgedTokens method of the mediator on the other network.
* Store information related to the bridged tokens in case the message execution fails on the other network
* and the action needs to be fixed/rolled back.
* @param _from address of sender, if bridge operation fails, tokens will be returned to this address
* @param _receiver address of receiver on the other side, will eventually receive bridged tokens
* @param _value bridged amount of tokens
*/
function passMessage(address _from, address _receiver, uint256 _value) internal {
bytes4 methodSelector = this.handleBridgedTokens.selector;
bytes memory data = abi.encodeWithSelector(methodSelector, _receiver, _value);
bytes32 _messageId = bridgeContract().requireToPassMessage(
mediatorContractOnOtherSide(),
data,
requestGasLimit()
);
setMessageValue(_messageId, _value);
setMessageRecipient(_messageId, _from);
}
/**
* @dev Handles the bridged tokens. Checks that the value is inside the execution limits and invokes the method
* to execute the Mint or Unlock accordingly.
* @param _recipient address that will receive the tokens
* @param _value amount of tokens to be received
*/
function handleBridgedTokens(address _recipient, uint256 _value) external {
require(msg.sender == address(bridgeContract()));
require(messageSender() == mediatorContractOnOtherSide());
if (withinExecutionLimit(_value)) {
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_value));
executeActionOnBridgedTokens(_recipient, _value);
} else {
executeActionOnBridgedTokensOutOfLimit(_recipient, _value);
}
}
/**
* @dev Method to be called when a bridged message execution failed. It will generate a new message requesting to
* fix/roll back the transferred assets on the other network.
* @param _messageId id of the message which execution failed.
*/
function requestFailedMessageFix(bytes32 _messageId) external {
require(!bridgeContract().messageCallStatus(_messageId));
require(bridgeContract().failedMessageReceiver(_messageId) == address(this));
require(bridgeContract().failedMessageSender(_messageId) == mediatorContractOnOtherSide());
bytes4 methodSelector = this.fixFailedMessage.selector;
bytes memory data = abi.encodeWithSelector(methodSelector, _messageId);
bridgeContract().requireToPassMessage(mediatorContractOnOtherSide(), data, requestGasLimit());
}
/**
* @dev Handles the request to fix transferred assets which bridged message execution failed on the other network.
* It uses the information stored by passMessage method when the assets were initially transferred
* @param _messageId id of the message which execution failed on the other network.
*/
function fixFailedMessage(bytes32 _messageId) external {
require(msg.sender == address(bridgeContract()));
require(messageSender() == mediatorContractOnOtherSide());
require(!messageFixed(_messageId));
address recipient = messageRecipient(_messageId);
uint256 value = messageValue(_messageId);
setMessageFixed(_messageId);
executeActionOnFixedTokens(recipient, value);
emit FailedMessageFixed(_messageId, recipient, value);
}
/* solcov ignore next */
function executeActionOnBridgedTokensOutOfLimit(address _recipient, uint256 _value) internal;
/* solcov ignore next */
function executeActionOnBridgedTokens(address _recipient, uint256 _value) internal;
/* solcov ignore next */
function executeActionOnFixedTokens(address _recipient, uint256 _value) internal;
}
// File: contracts/upgradeable_contracts/amb_erc677_to_erc677/BasicAMBErc677ToErc677.sol
pragma solidity 0.4.24;
/**
* @title BasicAMBErc677ToErc677
* @dev Common functionality for erc677-to-erc677 mediator intended to work on top of AMB bridge.
*/
contract BasicAMBErc677ToErc677 is
Initializable,
ReentrancyGuard,
Upgradeable,
Claimable,
VersionableBridge,
BaseOverdrawManagement,
BaseERC677Bridge,
TokenBridgeMediator
{
function initialize(
address _bridgeContract,
address _mediatorContract,
address _erc677token,
uint256[] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = _dailyLimit, 1 = _maxPerTx, 2 = _minPerTx ]
uint256[] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = _executionDailyLimit, 1 = _executionMaxPerTx ]
uint256 _requestGasLimit,
uint256 _decimalShift,
address _owner
) public onlyRelevantSender returns (bool) {
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]); // _executionMaxPerTx < _executionDailyLimit
_setBridgeContract(_bridgeContract);
_setMediatorContractOnOtherSide(_mediatorContract);
setErc677token(_erc677token);
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];
_setRequestGasLimit(_requestGasLimit);
uintStorage[DECIMAL_SHIFT] = _decimalShift;
setOwner(_owner);
setInitialize();
emit DailyLimitChanged(_dailyLimitMaxPerTxMinPerTxArray[0]);
emit ExecutionDailyLimitChanged(_executionDailyLimitExecutionMaxPerTxArray[0]);
return isInitialized();
}
function bridgeContractOnOtherSide() internal view returns (address) {
return mediatorContractOnOtherSide();
}
function relayTokens(address _from, address _receiver, uint256 _value) external {
require(_from == msg.sender || _from == _receiver);
_relayTokens(_from, _receiver, _value);
}
function _relayTokens(address _from, address _receiver, uint256 _value) internal {
// This lock is to prevent calling passMessage twice if a ERC677 token is used.
// When transferFrom is called, after the transfer, the ERC677 token will call onTokenTransfer from this contract
// which will call passMessage.
require(!lock());
ERC677 token = erc677token();
address to = address(this);
require(withinLimit(_value));
setTotalSpentPerDay(getCurrentDay(), totalSpentPerDay(getCurrentDay()).add(_value));
setLock(true);
token.transferFrom(_from, to, _value);
setLock(false);
bridgeSpecificActionsOnTokenTransfer(token, _from, _value, abi.encodePacked(_receiver));
}
function relayTokens(address _receiver, uint256 _value) external {
_relayTokens(msg.sender, _receiver, _value);
}
function onTokenTransfer(address _from, uint256 _value, bytes _data) external returns (bool) {
ERC677 oldXMoonToken = ERC677(0xC5C35D01B20f8d5cb65C60f02113EF6cd8e79910);
ERC677 token = erc677token();
require((msg.sender == address(token)) || (msg.sender == address(oldXMoonToken)));
if (!lock()) {
require(withinLimit(_value));
setTotalSpentPerDay(getCurrentDay(), totalSpentPerDay(getCurrentDay()).add(_value));
}
if (msg.sender == address(oldXMoonToken))
bridgeSpecificActionsOnTokenTransfer(oldXMoonToken, _from, _value, _data);
else
bridgeSpecificActionsOnTokenTransfer(token, _from, _value, _data);
return true;
}
function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) {
return (1, 1, 1);
}
function getBridgeMode() external pure returns (bytes4 _data) {
return 0x76595b56; // bytes4(keccak256(abi.encodePacked("erc-to-erc-amb")))
}
/**
* @dev Execute the action to be performed when the bridge tokens are out of execution limits.
* @param _recipient address intended to receive the tokens
* @param _value amount of tokens to be received
*/
function executeActionOnBridgedTokensOutOfLimit(address _recipient, uint256 _value) internal {
bytes32 _messageId = messageId();
address recipient;
uint256 value;
(recipient, value) = txAboveLimits(_messageId);
require(recipient == address(0) && value == 0);
setOutOfLimitAmount(outOfLimitAmount().add(_value));
setTxAboveLimits(_recipient, _value, _messageId);
emit AmountLimitExceeded(_recipient, _value, _messageId);
}
/**
* @dev Fixes locked tokens, that were out of execution limits during the call to handleBridgedTokens
* @param messageId reference for bridge operation that was out of execution limits
* @param unlockOnForeign true if fixed tokens should be unlocked to the other side of the bridge
* @param valueToUnlock unlocked amount of tokens, should be less than maxPerTx() and saved txAboveLimitsValue
*/
function fixAssetsAboveLimits(bytes32 messageId, bool unlockOnForeign, uint256 valueToUnlock)
external
onlyIfUpgradeabilityOwner
{
require(!fixedAssets(messageId));
require(valueToUnlock <= maxPerTx());
address recipient;
uint256 value;
(recipient, value) = txAboveLimits(messageId);
require(recipient != address(0) && value > 0 && value >= valueToUnlock);
setOutOfLimitAmount(outOfLimitAmount().sub(valueToUnlock));
uint256 pendingValue = value.sub(valueToUnlock);
setTxAboveLimitsValue(pendingValue, messageId);
emit AssetAboveLimitsFixed(messageId, valueToUnlock, pendingValue);
if (pendingValue == 0) {
setFixedAssets(messageId);
}
if (unlockOnForeign) {
passMessage(recipient, recipient, valueToUnlock);
}
}
function claimTokens(address _token, address _to) public onlyIfUpgradeabilityOwner validAddress(_to) {
claimValues(_token, _to);
}
}
// File: contracts/interfaces/IBurnableMintableERC677Token.sol
pragma solidity 0.4.24;
contract IBurnableMintableERC677Token is ERC677 {
function mint(address _to, uint256 _amount) public returns (bool);
function burn(uint256 _value) public;
function claimTokens(address _token, address _to) public;
}
// File: contracts/upgradeable_contracts/amb_erc677_to_erc677/HomeAMBErc677ToErc677.sol
pragma solidity 0.4.24;
/**
* @title HomeAMBErc677ToErc677
* @dev Home side implementation for erc677-to-erc677 mediator intended to work on top of AMB bridge.
* It is designed to be used as an implementation contract of EternalStorageProxy contract.
*/
contract HomeAMBErc677ToErc677 is BasicAMBErc677ToErc677 {
/**
* @dev Executes action on the request to deposit tokens relayed from the other network
* @param _recipient address of tokens receiver
* @param _value amount of bridged tokens
*/
function executeActionOnBridgedTokens(address _recipient, uint256 _value) internal {
uint256 value = _value.mul(10**decimalShift());
bytes32 _messageId = messageId();
IBurnableMintableERC677Token(erc677token()).mint(_recipient, value);
emit TokensBridged(_recipient, value, _messageId);
}
/**
* @dev Executes action on withdrawal of bridged tokens
* @param _token address of token contract
* @param _from address of tokens sender
* @param _value requsted amount of bridged tokens
* @param _data alternative receiver, if specified
*/
function bridgeSpecificActionsOnTokenTransfer(ERC677 _token, address _from, uint256 _value, bytes _data) internal {
if (!lock()) {
IBurnableMintableERC677Token(_token).burn(_value);
passMessage(_from, chooseReceiver(_from, _data), _value);
}
}
function executeActionOnFixedTokens(address _recipient, uint256 _value) internal {
IBurnableMintableERC677Token(erc677token()).mint(_recipient, _value);
}
// Selector: 0xf0ebb23e
function migrateToAnotherxMOONToken() external {
bytes32 migrateToAnotherxMOONTokenStorage = 0x850b0e45ac6387011aef8a3113b9f3fda9e1dea43ef0f51aa585cc9a30956629; // keccak256(abi.encodePacked("migrateToAnotherxMOONToken20200619"))
require(!boolStorage[migrateToAnotherxMOONTokenStorage]);
setErc677token(0x1e16aa4Df73d29C029d94CeDa3e3114EC191E25A);
boolStorage[migrateToAnotherxMOONTokenStorage] = true;
}
}

Contract ABI

[{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"relayTokens","inputs":[{"type":"address","name":"_receiver"},{"type":"uint256","name":"_value"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"fixFailedMessage","inputs":[{"type":"bytes32","name":"_messageId"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setBridgeContract","inputs":[{"type":"address","name":"_bridgeContract"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"erc677token","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"fixedAssets","inputs":[{"type":"bytes32","name":"_txHash"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"totalSpentPerDay","inputs":[{"type":"uint256","name":"_day"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isInitialized","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setExecutionDailyLimit","inputs":[{"type":"uint256","name":"_dailyLimit"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getCurrentDay","inputs":[],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"bytes4","name":"_data"}],"name":"getBridgeMode","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"executionDailyLimit","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"totalExecutedPerDay","inputs":[{"type":"uint256","name":"_day"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"messageFixed","inputs":[{"type":"bytes32","name":"_messageId"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"dailyLimit","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"claimTokens","inputs":[{"type":"address","name":"_token"},{"type":"address","name":"_to"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setMediatorContractOnOtherSide","inputs":[{"type":"address","name":"_mediatorContract"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"initialize","inputs":[{"type":"address","name":"_bridgeContract"},{"type":"address","name":"_mediatorContract"},{"type":"address","name":"_erc677token"},{"type":"uint256[]","name":"_dailyLimitMaxPerTxMinPerTxArray"},{"type":"uint256[]","name":"_executionDailyLimitExecutionMaxPerTxArray"},{"type":"uint256","name":"_requestGasLimit"},{"type":"uint256","name":"_decimalShift"},{"type":"address","name":"_owner"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"mediatorContractOnOtherSide","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"withinExecutionLimit","inputs":[{"type":"uint256","name":"_amount"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"executionMaxPerTx","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"handleBridgedTokens","inputs":[{"type":"address","name":"_recipient"},{"type":"uint256","name":"_value"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"owner","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"requestFailedMessageFix","inputs":[{"type":"bytes32","name":"_messageId"}],"constant":false},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"uint64","name":"major"},{"type":"uint64","name":"minor"},{"type":"uint64","name":"patch"}],"name":"getBridgeInterfacesVersion","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"outOfLimitAmount","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setMinPerTx","inputs":[{"type":"uint256","name":"_minPerTx"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"onTokenTransfer","inputs":[{"type":"address","name":"_from"},{"type":"uint256","name":"_value"},{"type":"bytes","name":"_data"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"fixAssetsAboveLimits","inputs":[{"type":"bytes32","name":"messageId"},{"type":"bool","name":"unlockOnForeign"},{"type":"uint256","name":"valueToUnlock"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"relayTokens","inputs":[{"type":"address","name":"_from"},{"type":"address","name":"_receiver"},{"type":"uint256","name":"_value"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setDailyLimit","inputs":[{"type":"uint256","name":"_dailyLimit"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"requestGasLimit","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setMaxPerTx","inputs":[{"type":"uint256","name":"_maxPerTx"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"bridgeContract","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"decimalShift","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"minPerTx","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"withinLimit","inputs":[{"type":"uint256","name":"_amount"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"migrateToAnotherxMOONToken","inputs":[],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setExecutionMaxPerTx","inputs":[{"type":"uint256","name":"_maxPerTx"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setRequestGasLimit","inputs":[{"type":"uint256","name":"_requestGasLimit"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"maxPerTx","inputs":[],"constant":true},{"type":"event","name":"FailedMessageFixed","inputs":[{"type":"bytes32","name":"messageId","indexed":true},{"type":"address","name":"recipient","indexed":false},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"event","name":"TokensBridged","inputs":[{"type":"address","name":"recipient","indexed":true},{"type":"uint256","name":"value","indexed":false},{"type":"bytes32","name":"messageId","indexed":true}],"anonymous":false},{"type":"event","name":"DailyLimitChanged","inputs":[{"type":"uint256","name":"newLimit","indexed":false}],"anonymous":false},{"type":"event","name":"ExecutionDailyLimitChanged","inputs":[{"type":"uint256","name":"newLimit","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","indexed":false},{"type":"address","name":"newOwner","indexed":false}],"anonymous":false},{"type":"event","name":"AmountLimitExceeded","inputs":[{"type":"address","name":"recipient","indexed":false},{"type":"uint256","name":"value","indexed":false},{"type":"bytes32","name":"transactionHash","indexed":false}],"anonymous":false},{"type":"event","name":"AssetAboveLimitsFixed","inputs":[{"type":"bytes32","name":"transactionHash","indexed":true},{"type":"uint256","name":"value","indexed":false},{"type":"uint256","name":"remaining","indexed":false}],"anonymous":false}]
            

Contract Byte Code

0x6080604052600436106101f9576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806301e4f53a146101fe5780630950d5151461024b5780630b26cf661461027c57806318d8f9c9146102bf5780632888bb9c146103165780632bd0bb051461035f578063392e53cd146103a05780633dd95d1b146103cf5780633e6968b6146103fc578063437764df1461042757806343b37dd3146104905780634fb3fef7146104bb57806359339982146104fc57806367eeba0c1461054557806369ffa08a146105705780636e5d6bea146105d35780637acee4b014610616578063871c07601461076b578063879ce676146107c25780638aa1949a146108075780638b6c0354146108325780638da5cb5b1461087f5780639a4a4395146108d65780639cb7595a14610907578063a01893451461097c578063a2a6ca27146109a7578063a4c0ed36146109d4578063a7444c0d14610a51578063ad58bdd114610a98578063b20d30a914610b05578063be3b625b14610b32578063c6f6f21614610b5d578063cd59658314610b8a578063dae5f0fd14610be1578063df25f3f014610c0c578063ea9f496814610c37578063f0ebb23e14610c7c578063f20151e114610c93578063f2fde38b14610cc0578063f3b8379114610d03578063f968adbe14610d30575b600080fd5b34801561020a57600080fd5b50610249600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d5b565b005b34801561025757600080fd5b5061027a6004803603810190808035600019169060200190929190505050610d6a565b005b34801561028857600080fd5b506102bd600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ea9565b005b3480156102cb57600080fd5b506102d4610ef6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561032257600080fd5b506103456004803603810190808035600019169060200190929190505050610f5c565b604051808215151515815260200191505060405180910390f35b34801561036b57600080fd5b5061038a6004803603810190808035906020019092919050505061103f565b6040518082815260200191505060405180910390f35b3480156103ac57600080fd5b506103b561110c565b604051808215151515815260200191505060405180910390f35b3480156103db57600080fd5b506103fa6004803603810190808035906020019092919050505061115f565b005b34801561040857600080fd5b5061041161123c565b6040518082815260200191505060405180910390f35b34801561043357600080fd5b5061043c611252565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b34801561049c57600080fd5b506104a561127d565b6040518082815260200191505060405180910390f35b3480156104c757600080fd5b506104e6600480360381019080803590602001909291905050506112c2565b6040518082815260200191505060405180910390f35b34801561050857600080fd5b5061052b600480360381019080803560001916906020019092919050505061138f565b604051808215151515815260200191505060405180910390f35b34801561055157600080fd5b5061055a611472565b6040518082815260200191505060405180910390f35b34801561057c57600080fd5b506105d1600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114b7565b005b3480156105df57600080fd5b50610614600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115db565b005b34801561062257600080fd5b50610751600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091929192908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611628565b604051808215151515815260200191505060405180910390f35b34801561077757600080fd5b50610780611c29565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107ce57600080fd5b506107ed60048036038101908080359060200190929190505050611c8f565b604051808215151515815260200191505060405180910390f35b34801561081357600080fd5b5061081c611cdc565b6040518082815260200191505060405180910390f35b34801561083e57600080fd5b5061087d600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611d21565b005b34801561088b57600080fd5b50610894611e08565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156108e257600080fd5b506109056004803603810190808035600019169060200190929190505050611e6e565b005b34801561091357600080fd5b5061091c612327565b604051808467ffffffffffffffff1667ffffffffffffffff1681526020018367ffffffffffffffff1667ffffffffffffffff1681526020018267ffffffffffffffff1667ffffffffffffffff168152602001935050505060405180910390f35b34801561098857600080fd5b50610991612345565b6040518082815260200191505060405180910390f35b3480156109b357600080fd5b506109d26004803603810190808035906020019092919050505061238a565b005b3480156109e057600080fd5b50610a37600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001919091929391929390505050612443565b604051808215151515815260200191505060405180910390f35b348015610a5d57600080fd5b50610a966004803603810190808035600019169060200190929190803515159060200190929190803590602001909291905050506125f2565b005b348015610aa457600080fd5b50610b03600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612811565b005b348015610b1157600080fd5b50610b3060048036038101908080359060200190929190505050612891565b005b348015610b3e57600080fd5b50610b4761296e565b6040518082815260200191505060405180910390f35b348015610b6957600080fd5b50610b88600480360381019080803590602001909291905050506129b3565b005b348015610b9657600080fd5b50610b9f612a6b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610bed57600080fd5b50610bf6612ad1565b6040518082815260200191505060405180910390f35b348015610c1857600080fd5b50610c21612b16565b6040518082815260200191505060405180910390f35b348015610c4357600080fd5b50610c6260048036038101908080359060200190929190505050612b5b565b604051808215151515815260200191505060405180910390f35b348015610c8857600080fd5b50610c91612bbb565b005b348015610c9f57600080fd5b50610cbe60048036038101908080359060200190929190505050612c6c565b005b348015610ccc57600080fd5b50610d01600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612d07565b005b348015610d0f57600080fd5b50610d2e60048036038101908080359060200190929190505050612d90565b005b348015610d3c57600080fd5b50610d45612ddd565b6040518082815260200191505060405180910390f35b610d66338383612e22565b5050565b600080610d75612a6b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610dae57600080fd5b610db6611c29565b73ffffffffffffffffffffffffffffffffffffffff16610dd4613020565b73ffffffffffffffffffffffffffffffffffffffff16141515610df657600080fd5b610dff8361138f565b151515610e0b57600080fd5b610e14836130cd565b9150610e1f836131c3565b9050610e2a83613298565b610e348282613380565b82600019167f06297b0797e3363e96e454edd4ab62862051bf559a7a431ce09415306771d1338383604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a2505050565b610eb1611e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610eea57600080fd5b610ef38161346a565b50565b6000600260007fa8b0ade3e2b734f043ce298aca4cc8d19d74270223f34531d0988b7d00cba21d6001026000191660001916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600460008360405160200180807f6669786564417373657473000000000000000000000000000000000000000000815250600b0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b602083101515610fe75780518252602082019150602081019050602083039250610fc2565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060009054906101000a900460ff169050919050565b60008060008360405160200180807f746f74616c5370656e74506572446179000000000000000000000000000000008152506010018281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831015156110c1578051825260208201915060208101905060208303925061109c565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020549050919050565b6000600460007f0a6f646cd611241d8073675e00d1a1ff700fbf1b53fcf473de56d1e6e4b714ba6001026000191660001916815260200190815260200160002060009054906101000a900460ff16905090565b611167611e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156111a057600080fd5b6111a8611cdc565b8111806111b55750600081145b15156111c057600080fd5b806000807f21dbcab260e413c20dc13c28b7db95e2b423d1135f42bb8b7d5214a92270d23760010260001916600019168152602001908152602001600020819055507f9bebf928b90863f24cc31f726a3a7545efd409f1dcf552301b1ee3710da70d3b816040518082815260200191505060405180910390a150565b6000620151804281151561124c57fe5b04905090565b60006376595b567c010000000000000000000000000000000000000000000000000000000002905090565b60008060007f21dbcab260e413c20dc13c28b7db95e2b423d1135f42bb8b7d5214a92270d2376001026000191660001916815260200190815260200160002054905090565b60008060008360405160200180807f746f74616c4578656375746564506572446179000000000000000000000000008152506013018281526020019150506040516020818303038152906040526040518082805190602001908083835b602083101515611344578051825260208201915060208101905060208303925061131f565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020549050919050565b6000600460008360405160200180807f6d65737361676546697865640000000000000000000000000000000000000000815250600c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b60208310151561141a57805182526020820191506020810190506020830392506113f5565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060009054906101000a900460ff169050919050565b60008060007f4a6a899679f26b73530d8cf1001e83b6f7702e04b6fdb98f3c62dc7e47e041a56001026000191660001916815260200190815260200160002054905090565b3073ffffffffffffffffffffffffffffffffffffffff16636fde82026040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561151b57600080fd5b505af115801561152f573d6000803e3d6000fd5b505050506040513d602081101561154557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561158f57600080fd5b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156115cc57600080fd5b6115d683836134fe565b505050565b6115e3611e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561161c57600080fd5b61162581613550565b50565b60003073ffffffffffffffffffffffffffffffffffffffff16636fde82027c010000000000000000000000000000000000000000000000000000000002604051602401604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405180828051906020019080838360005b838110156116f55780820151818401526020810190506116da565b50505050905090810190601f1680156117225780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1915050158061180c57503073ffffffffffffffffffffffffffffffffffffffff16636fde82026040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156117a257600080fd5b505af11580156117b6573d6000803e3d6000fd5b505050506040513d60208110156117cc57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b8061184257503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561184d57600080fd5b61185561110c565b15151561186157600080fd5b600086600281518110151561187257fe5b906020019060200201511180156118b8575085600281518110151561189357fe5b906020019060200201518660018151811015156118ac57fe5b90602001906020020151115b80156118f357508560018151811015156118ce57fe5b906020019060200201518660008151811015156118e757fe5b90602001906020020151115b15156118fe57600080fd5b84600081518110151561190d57fe5b9060200190602002015185600181518110151561192657fe5b9060200190602002015110151561193c57600080fd5b6119458961346a565b61194e88613550565b611957876135d0565b85600081518110151561196657fe5b906020019060200201516000807f4a6a899679f26b73530d8cf1001e83b6f7702e04b6fdb98f3c62dc7e47e041a560010260001916600019168152602001908152602001600020819055508560018151811015156119c057fe5b906020019060200201516000807f0f8803acad17c63ee38bf2de71e1888bc7a079a6f73658e274b08018bea4e29c6001026000191660001916815260200190815260200160002081905550856002815181101515611a1a57fe5b906020019060200201516000807fbbb088c505d18e049d114c7c91f11724e69c55ad6c5397e2b929e68b41fa05d16001026000191660001916815260200190815260200160002081905550846000815181101515611a7457fe5b906020019060200201516000807f21dbcab260e413c20dc13c28b7db95e2b423d1135f42bb8b7d5214a92270d2376001026000191660001916815260200190815260200160002081905550846001815181101515611ace57fe5b906020019060200201516000807fc0ed44c192c86d1cc1ba51340b032c2766b4a2b0041031de13c46dd7104888d56001026000191660001916815260200190815260200160002081905550611b2284613664565b826000807f1e8ecaafaddea96ed9ac6d2642dcdfe1bebe58a930b1085842d8fc122b371ee56001026000191660001916815260200190815260200160002081905550611b6d826136bf565b611b756137dd565b7fad4123ae17c414d9c6d2fec478b402e6b01856cc250fd01fbfd252fda0089d3c866000815181101515611ba557fe5b906020019060200201516040518082815260200191505060405180910390a17f9bebf928b90863f24cc31f726a3a7545efd409f1dcf552301b1ee3710da70d3b856000815181101515611bf457fe5b906020019060200201516040518082815260200191505060405180910390a1611c1b61110c565b905098975050505050505050565b6000600260007f98aa806e31e94a687a31c65769cb99670064dd7f5a87526da075c5fb4eab98806001026000191660001916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080611cb483611ca6611ca161123c565b6112c2565b61383690919063ffffffff16565b905080611cbf61127d565b10158015611cd45750611cd0611cdc565b8311155b915050919050565b60008060007fc0ed44c192c86d1cc1ba51340b032c2766b4a2b0041031de13c46dd7104888d56001026000191660001916815260200190815260200160002054905090565b611d29612a6b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611d6257600080fd5b611d6a611c29565b73ffffffffffffffffffffffffffffffffffffffff16611d88613020565b73ffffffffffffffffffffffffffffffffffffffff16141515611daa57600080fd5b611db381611c8f565b15611df957611dea611dc361123c565b611de583611dd7611dd261123c565b6112c2565b61383690919063ffffffff16565b613852565b611df4828261391e565b611e04565b611e038282613a89565b5b5050565b6000600260007f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c06001026000191660001916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006060611e7a612a6b565b73ffffffffffffffffffffffffffffffffffffffff1663cb08a10c846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b158015611ef057600080fd5b505af1158015611f04573d6000803e3d6000fd5b505050506040513d6020811015611f1a57600080fd5b8101908080519060200190929190505050151515611f3757600080fd5b3073ffffffffffffffffffffffffffffffffffffffff16611f56612a6b565b73ffffffffffffffffffffffffffffffffffffffff16633f9a8e7e856040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b158015611fcc57600080fd5b505af1158015611fe0573d6000803e3d6000fd5b505050506040513d6020811015611ff657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614151561202957600080fd5b612031611c29565b73ffffffffffffffffffffffffffffffffffffffff1661204f612a6b565b73ffffffffffffffffffffffffffffffffffffffff16634a610b04856040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1580156120c557600080fd5b505af11580156120d9573d6000803e3d6000fd5b505050506040513d60208110156120ef57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614151561212257600080fd5b630950d5157c01000000000000000000000000000000000000000000000000000000000291508183604051602401808260001916600019168152602001915050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506121c9612a6b565b73ffffffffffffffffffffffffffffffffffffffff1663dc8601b36121ec611c29565b836121f561296e565b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561229857808201518184015260208101905061227d565b50505050905090810190601f1680156122c55780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156122e657600080fd5b505af11580156122fa573d6000803e3d6000fd5b505050506040513d602081101561231057600080fd5b810190808051906020019092919050505050505050565b60008060006001806001829250819150809050925092509250909192565b60008060007f145286dc85799b6fb9fe322391ba2d95683077b2adf34dd576dedc437e537ba76001026000191660001916815260200190815260200160002054905090565b612392611e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156123cb57600080fd5b6000811180156123e157506123de611472565b81105b80156123f357506123f0612ddd565b81105b15156123fe57600080fd5b806000807fbbb088c505d18e049d114c7c91f11724e69c55ad6c5397e2b929e68b41fa05d1600102600019166000191681526020019081526020016000208190555050565b600080600073c5c35d01b20f8d5cb65c60f02113ef6cd8e799109150612467610ef6565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806124ce57508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156124d957600080fd5b6124e1613b9f565b151561252e576124f086612b5b565b15156124fb57600080fd5b61252d61250661123c565b6125288861251a61251561123c565b61103f565b61383690919063ffffffff16565b613bf2565b5b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156125a5576125a082888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050613cbe565b6125e4565b6125e381888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050613cbe565b5b600192505050949350505050565b60008060003073ffffffffffffffffffffffffffffffffffffffff16636fde82026040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561265b57600080fd5b505af115801561266f573d6000803e3d6000fd5b505050506040513d602081101561268557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156126cf57600080fd5b6126d886610f5c565b1515156126e457600080fd5b6126ec612ddd565b84111515156126fa57600080fd5b61270386613d6e565b8093508194505050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156127485750600082115b80156127545750838210155b151561275f57600080fd5b61278161277c8561276e612345565b613f3390919063ffffffff16565b613f4c565b6127948483613f3390919063ffffffff16565b90506127a08187613f91565b85600019167f5bcec6564fe8d2cbb4e4eb8237510ceb6b291a5c2ee2e429948d25e9c924c1fa8583604051808381526020018281526020019250505060405180910390a260008114156127f7576127f686614065565b5b84156128095761280883848661414d565b5b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16148061287657508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b151561288157600080fd5b61288c838383612e22565b505050565b612899611e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156128d257600080fd5b6128da612ddd565b8111806128e75750600081145b15156128f257600080fd5b806000807f4a6a899679f26b73530d8cf1001e83b6f7702e04b6fdb98f3c62dc7e47e041a560010260001916600019168152602001908152602001600020819055507fad4123ae17c414d9c6d2fec478b402e6b01856cc250fd01fbfd252fda0089d3c816040518082815260200191505060405180910390a150565b60008060007f2dfd6c9f781bb6bbb5369c114e949b69ebb440ef3d4dd6b2836225eb1dc3a2be6001026000191660001916815260200190815260200160002054905090565b6129bb611e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156129f457600080fd5b6000811480612a1b5750612a06612b16565b81118015612a1a5750612a17611472565b81105b5b1515612a2657600080fd5b806000807f0f8803acad17c63ee38bf2de71e1888bc7a079a6f73658e274b08018bea4e29c600102600019166000191681526020019081526020016000208190555050565b6000600260007f811bbb11e8899da471f0e69a3ed55090fc90215227fc5fb1cb0d6e962ea7b74f6001026000191660001916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060007f1e8ecaafaddea96ed9ac6d2642dcdfe1bebe58a930b1085842d8fc122b371ee56001026000191660001916815260200190815260200160002054905090565b60008060007fbbb088c505d18e049d114c7c91f11724e69c55ad6c5397e2b929e68b41fa05d16001026000191660001916815260200190815260200160002054905090565b600080612b8083612b72612b6d61123c565b61103f565b61383690919063ffffffff16565b905080612b8b611472565b10158015612ba05750612b9c612ddd565b8311155b8015612bb35750612baf612b16565b8310155b915050919050565b60007f850b0e45ac6387011aef8a3113b9f3fda9e1dea43ef0f51aa585cc9a30956629600102905060046000826000191660001916815260200190815260200160002060009054906101000a900460ff16151515612c1857600080fd5b612c35731e16aa4df73d29c029d94ceda3e3114ec191e25a6135d0565b600160046000836000191660001916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b612c74611e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612cad57600080fd5b612cb561127d565b81101515612cc257600080fd5b806000807fc0ed44c192c86d1cc1ba51340b032c2766b4a2b0041031de13c46dd7104888d5600102600019166000191681526020019081526020016000208190555050565b612d0f611e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612d4857600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612d8457600080fd5b612d8d816136bf565b50565b612d98611e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612dd157600080fd5b612dda81613664565b50565b60008060007f0f8803acad17c63ee38bf2de71e1888bc7a079a6f73658e274b08018bea4e29c6001026000191660001916815260200190815260200160002054905090565b600080612e2d613b9f565b151515612e3957600080fd5b612e41610ef6565b9150309050612e4f83612b5b565b1515612e5a57600080fd5b612e8c612e6561123c565b612e8785612e79612e7461123c565b61103f565b61383690919063ffffffff16565b613bf2565b612e96600161439c565b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd8683866040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015612f6d57600080fd5b505af1158015612f81573d6000803e3d6000fd5b505050506040513d6020811015612f9757600080fd5b810190808051906020019092919050505050612fb3600061439c565b61301982868587604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c01000000000000000000000000028152601401915050604051602081830303815290604052613cbe565b5050505050565b600061302a612a6b565b73ffffffffffffffffffffffffffffffffffffffff1663d67bdd256040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561308d57600080fd5b505af11580156130a1573d6000803e3d6000fd5b505050506040513d60208110156130b757600080fd5b8101908080519060200190929190505050905090565b6000600260008360405160200180807f6d657373616765526563697069656e740000000000000000000000000000000081525060100182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831015156131585780518252602082019150602081019050602083039250613133565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60008060008360405160200180807f6d65737361676556616c75650000000000000000000000000000000000000000815250600c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b60208310151561324d5780518252602082019150602081019050602083039250613228565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020549050919050565b6001600460008360405160200180807f6d65737361676546697865640000000000000000000000000000000000000000815250600c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b60208310151561332357805182526020820191506020810190506020830392506132fe565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b613388610ef6565b73ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561342a57600080fd5b505af115801561343e573d6000803e3d6000fd5b505050506040513d602081101561345457600080fd5b8101908080519060200190929190505050505050565b613473816143f5565b151561347e57600080fd5b80600260007f811bbb11e8899da471f0e69a3ed55090fc90215227fc5fb1cb0d6e962ea7b74f6001026000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156135415761353c81614408565b61354c565b61354b8282614432565b5b5050565b80600260007f98aa806e31e94a687a31c65769cb99670064dd7f5a87526da075c5fb4eab98806001026000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6135d9816143f5565b15156135e457600080fd5b80600260007fa8b0ade3e2b734f043ce298aca4cc8d19d74270223f34531d0988b7d00cba21d6001026000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61366c614521565b811115151561367a57600080fd5b806000807f2dfd6c9f781bb6bbb5369c114e949b69ebb440ef3d4dd6b2836225eb1dc3a2be600102600019166000191681526020019081526020016000208190555050565b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e06136e8611e08565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a180600260007f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c06001026000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6001600460007f0a6f646cd611241d8073675e00d1a1ff700fbf1b53fcf473de56d1e6e4b714ba6001026000191660001916815260200190815260200160002060006101000a81548160ff021916908315150217905550565b6000818301905082811015151561384957fe5b80905092915050565b806000808460405160200180807f746f74616c4578656375746564506572446179000000000000000000000000008152506013018281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831015156138d357805182526020820191506020810190506020830392506138ae565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020819055505050565b60008061393e61392c612ad1565b600a0a846145ce90919063ffffffff16565b9150613948614606565b9050613952610ef6565b73ffffffffffffffffffffffffffffffffffffffff166340c10f1985846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156139f457600080fd5b505af1158015613a08573d6000803e3d6000fd5b505050506040513d6020811015613a1e57600080fd5b81019080805190602001909291905050505080600019168473ffffffffffffffffffffffffffffffffffffffff167f2f9a6098d4503a127779ba975f5f6b04f842362b1809f346989e9abc0b4dedb6846040518082815260200191505060405180910390a350505050565b6000806000613a96614606565b9250613aa183613d6e565b8092508193505050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148015613ae55750600081145b1515613af057600080fd5b613b12613b0d85613aff612345565b61383690919063ffffffff16565b613f4c565b613b1d8585856146b3565b7f159c0773f543f1e17d5e78327702770947055eb4e871b529bbc78bc9fde45692858585604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018260001916600019168152602001935050505060405180910390a15050505050565b6000600460007f6168652c307c1e813ca11cfb3a601f1cf3b22452021a5052d8b05f1f1f8a3e926001026000191660001916815260200190815260200160002060009054906101000a900460ff16905090565b806000808460405160200180807f746f74616c5370656e74506572446179000000000000000000000000000000008152506010018281526020019150506040516020818303038152906040526040518082805190602001908083835b602083101515613c735780518252602082019150602081019050602083039250613c4e565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020819055505050565b613cc6613b9f565b1515613d68578373ffffffffffffffffffffffffffffffffffffffff166342966c68836040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b158015613d3b57600080fd5b505af1158015613d4f573d6000803e3d6000fd5b50505050613d6783613d6185846147cd565b8461414d565b5b50505050565b600080600260008460405160200180807f74784f75744f664c696d6974526563697069656e74000000000000000000000081525060150182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b602083101515613dfa5780518252602082019150602081019050602083039250613dd5565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691506000808460405160200180807f74784f75744f664c696d697456616c756500000000000000000000000000000081525060110182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b602083101515613ee85780518252602082019150602081019050602083039250613ec3565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020549050915091565b6000828211151515613f4157fe5b818303905092915050565b806000807f145286dc85799b6fb9fe322391ba2d95683077b2adf34dd576dedc437e537ba7600102600019166000191681526020019081526020016000208190555050565b816000808360405160200180807f74784f75744f664c696d697456616c756500000000000000000000000000000081525060110182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b60208310151561401a5780518252602082019150602081019050602083039250613ff5565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020819055505050565b6001600460008360405160200180807f6669786564417373657473000000000000000000000000000000000000000000815250600b0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831015156140f057805182526020820191506020810190506020830392506140cb565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600060606000638b6c03547c0100000000000000000000000000000000000000000000000000000000029250828585604051602401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509150614226612a6b565b73ffffffffffffffffffffffffffffffffffffffff1663dc8601b3614249611c29565b8461425261296e565b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156142f55780820151818401526020810190506142da565b50505050905090810190601f1680156143225780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561434357600080fd5b505af1158015614357573d6000803e3d6000fd5b505050506040513d602081101561436d57600080fd5b8101908080519060200190929190505050905061438a818561487c565b6143948187614950565b505050505050565b80600460007f6168652c307c1e813ca11cfb3a601f1cf3b22452021a5052d8b05f1f1f8a3e926001026000191660001916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b905060008111915050919050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905061442e8282614a5f565b5050565b6000808391508173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1580156144d357600080fd5b505af11580156144e7573d6000803e3d6000fd5b505050506040513d60208110156144fd57600080fd5b8101908080519060200190929190505050905061451b848483614afe565b50505050565b600061452b612a6b565b73ffffffffffffffffffffffffffffffffffffffff1663e5789d036040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561458e57600080fd5b505af11580156145a2573d6000803e3d6000fd5b505050506040513d60208110156145b857600080fd5b8101908080519060200190929190505050905090565b6000808314156145e15760009050614600565b81830290508183828115156145f257fe5b041415156145fc57fe5b8090505b92915050565b6000614610612a6b565b73ffffffffffffffffffffffffffffffffffffffff1663669f618b6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561467357600080fd5b505af1158015614687573d6000803e3d6000fd5b505050506040513d602081101561469d57600080fd5b8101908080519060200190929190505050905090565b82600260008360405160200180807f74784f75744f664c696d6974526563697069656e74000000000000000000000081525060150182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b60208310151561473d5780518252602082019150602081019050602083039250614718565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506147c88282613f91565b505050565b600082905060008251111561487657601482511415156147ec57600080fd5b6147f582614c19565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561483357600080fd5b61483b614c27565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561487557600080fd5b5b92915050565b806000808460405160200180807f6d65737361676556616c75650000000000000000000000000000000000000000815250600c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b60208310151561490557805182526020820191506020810190506020830392506148e0565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020819055505050565b80600260008460405160200180807f6d657373616765526563697069656e740000000000000000000000000000000081525060100182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831015156149da57805182526020820191506020810190506020830392506149b5565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515614afa578082614aa4614c36565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019150506040518091039082f080158015614af5573d6000803e3d6000fd5b509050505b5050565b60606000606063a9059cbb7c0100000000000000000000000000000000000000000000000000000000028585604051602401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506020600082516020840160008a5af1600051935060005192508060008114614bf357614bf8565b600080fd5b5050600083511115614c1157811515614c1057600080fd5b5b505050505050565b600060148201519050919050565b6000614c31611c29565b905090565b604051603f80614c468339019056006080604052604051602080603f833981018060405281019080805190602001909291905050508073ffffffffffffffffffffffffffffffffffffffff16ff00a165627a7a72305820865cb8bdee21a63ac1beca624af54ac015c6db33a200d6bddbc05f36cc0fc0440029