creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/upgradeable_contracts/arbitrary_message/HomeAMB.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"./AsyncInformationProcessor.sol\";\n\ncontract HomeAMB is AsyncInformationProcessor {\n    event UserRequestForSignature(bytes32 indexed messageId, bytes encodedData);\n    event AffirmationCompleted(\n        address indexed sender,\n        address indexed executor,\n        bytes32 indexed messageId,\n        bool status\n    );\n\n    function emitEventOnMessageRequest(bytes32 messageId, bytes encodedData) internal {\n        emit UserRequestForSignature(messageId, encodedData);\n    }\n\n    function emitEventOnMessageProcessed(address sender, address executor, bytes32 messageId, bool status) internal {\n        emit AffirmationCompleted(sender, executor, messageId, status);\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/arbitrary_message/AsyncInformationProcessor.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../../interfaces/IAMBInformationReceiver.sol\";\nimport \"./BasicHomeAMB.sol\";\n\n/**\n * @title AsyncInformationProcessor\n * @dev Functionality for making and processing async calls on Home side of the AMB.\n */\ncontract AsyncInformationProcessor is BasicHomeAMB {\n    event UserRequestForInformation(\n        bytes32 indexed messageId,\n        bytes32 indexed requestSelector,\n        address indexed sender,\n        bytes data\n    );\n    event SignedForInformation(address indexed signer, bytes32 indexed messageId);\n    event InformationRetrieved(bytes32 indexed messageId, bool status, bool callbackStatus);\n    event EnabledAsyncRequestSelector(bytes32 indexed requestSelector, bool enable);\n\n    /**\n     * @dev Makes an asynchronous request to get information from the opposite network.\n     * Call result will be returned later to the callee, by using the onInformationReceived(bytes) callback function.\n     * @param _requestSelector selector for the async request.\n     * @param _data payload for the given selector\n     */\n    function requireToGetInformation(bytes32 _requestSelector, bytes _data) external returns (bytes32) {\n        // it is not allowed to pass messages while other messages are processed\n        // if other is not explicitly configured\n        require(messageId() == bytes32(0) || allowReentrantRequests());\n        // only contracts are allowed to call this method, since EOA won't be able to receive a callback.\n        require(AddressUtils.isContract(msg.sender));\n\n        require(isAsyncRequestSelectorEnabled(_requestSelector));\n\n        bytes32 _messageId = _getNewMessageId(sourceChainId());\n\n        _setAsyncRequestSender(_messageId, msg.sender);\n\n        emit UserRequestForInformation(_messageId, _requestSelector, msg.sender, _data);\n        return _messageId;\n    }\n\n    /**\n     * Tells if the specific async request selector is allowed to be used and supported by the bridge oracles.\n     * @param _requestSelector selector for the async request.\n     * @return true, if selector is allowed to be used.\n     */\n    function isAsyncRequestSelectorEnabled(bytes32 _requestSelector) public view returns (bool) {\n        return boolStorage[keccak256(abi.encodePacked(\"enableRequestSelector\", _requestSelector))];\n    }\n\n    /**\n     * Enables or disables the specific async request selector.\n     * Only owner can call this method.\n     * @param _requestSelector selector for the async request.\n     * @param _enable true, if the selector should be allowed.\n     */\n    function enableAsyncRequestSelector(bytes32 _requestSelector, bool _enable) external onlyOwner {\n        boolStorage[keccak256(abi.encodePacked(\"enableRequestSelector\", _requestSelector))] = _enable;\n\n        emit EnabledAsyncRequestSelector(_requestSelector, _enable);\n    }\n\n    /**\n     * @dev Submits result of the async call.\n     * Only validators are allowed to call this method.\n     * Once enough confirmations are collected, callback function is called.\n     * @param _messageId unique id of the request that was previously made.\n     * @param _status true, if JSON-RPC request succeeded, false otherwise.\n     * @param _result call result returned by the other side of the bridge.\n     */\n    function confirmInformation(bytes32 _messageId, bool _status, bytes _result) external onlyValidator {\n        bytes32 hashMsg = keccak256(abi.encodePacked(_messageId, _status, _result));\n        bytes32 hashSender = keccak256(abi.encodePacked(msg.sender, hashMsg));\n        // Duplicated confirmations\n        require(!affirmationsSigned(hashSender));\n        setAffirmationsSigned(hashSender, true);\n\n        uint256 signed = numAffirmationsSigned(hashMsg);\n        require(!isAlreadyProcessed(signed));\n        // the check above assumes that the case when the value could be overflew will not happen in the addition operation below\n        signed = signed + 1;\n\n        setNumAffirmationsSigned(hashMsg, signed);\n\n        emit SignedForInformation(msg.sender, _messageId);\n\n        if (signed >= requiredSignatures()) {\n            setNumAffirmationsSigned(hashMsg, markAsProcessed(signed));\n            address sender = _restoreAsyncRequestSender(_messageId);\n            bytes memory data = abi.encodeWithSelector(\n                IAMBInformationReceiver(address(0)).onInformationReceived.selector,\n                _messageId,\n                _status,\n                _result\n            );\n            uint256 gas = maxGasPerTx();\n            require((gasleft() * 63) / 64 > gas);\n\n            bool callbackStatus = sender.call.gas(gas)(data);\n\n            emit InformationRetrieved(_messageId, _status, callbackStatus);\n        }\n    }\n\n    /**\n     * Internal function for saving async request sender for future use.\n     * @param _messageId id of the sent async request.\n     * @param _sender address of the request sender, receiver of the callback.\n     */\n    function _setAsyncRequestSender(bytes32 _messageId, address _sender) internal {\n        addressStorage[keccak256(abi.encodePacked(\"asyncSender\", _messageId))] = _sender;\n    }\n\n    /**\n     * Internal function for restoring async request sender information.\n     * @param _messageId id of the sent async request.\n     * @return address of async request sender and callback receiver.\n     */\n    function _restoreAsyncRequestSender(bytes32 _messageId) internal returns (address) {\n        bytes32 hash = keccak256(abi.encodePacked(\"asyncSender\", _messageId));\n        address sender = addressStorage[hash];\n\n        require(sender != address(0));\n\n        delete addressStorage[hash];\n        return sender;\n    }\n}\n"
      },
      "contracts/interfaces/IAMBInformationReceiver.sol": {
        "content": "pragma solidity 0.4.24;\n\ninterface IAMBInformationReceiver {\n    function onInformationReceived(bytes32 messageId, bool status, bytes result) external;\n}\n"
      },
      "contracts/upgradeable_contracts/arbitrary_message/BasicHomeAMB.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../../libraries/Message.sol\";\nimport \"../../libraries/ArbitraryMessage.sol\";\nimport \"./BasicAMB.sol\";\nimport \"./MessageDelivery.sol\";\n\ncontract BasicHomeAMB is BasicAMB, MessageDelivery {\n    event SignedForUserRequest(address indexed signer, bytes32 messageHash);\n    event SignedForAffirmation(address indexed signer, bytes32 messageHash);\n\n    event CollectedSignatures(\n        address authorityResponsibleForRelay,\n        bytes32 messageHash,\n        uint256 NumberOfCollectedSignatures\n    );\n\n    uint256 internal constant SEND_TO_MANUAL_LANE = 0x80;\n\n    function executeAffirmation(bytes message) external onlyValidator {\n        bytes32 hashMsg = keccak256(abi.encodePacked(message));\n        bytes32 hashSender = keccak256(abi.encodePacked(msg.sender, hashMsg));\n        // Duplicated affirmations\n        require(!affirmationsSigned(hashSender));\n        setAffirmationsSigned(hashSender, true);\n\n        uint256 signed = numAffirmationsSigned(hashMsg);\n        require(!isAlreadyProcessed(signed));\n        // the check above assumes that the case when the value could be overflew will not happen in the addition operation below\n        signed = signed + 1;\n\n        setNumAffirmationsSigned(hashMsg, signed);\n\n        emit SignedForAffirmation(msg.sender, hashMsg);\n\n        if (signed >= requiredSignatures()) {\n            setNumAffirmationsSigned(hashMsg, markAsProcessed(signed));\n            handleMessage(message);\n        }\n    }\n\n    /**\n    * @dev Requests message relay to the opposite network, message is sent to the manual lane.\n    * @param _contract executor address on the other side.\n    * @param _data calldata passed to the executor on the other side.\n    * @param _gas gas limit used on the other network for executing a message.\n    */\n    function requireToConfirmMessage(address _contract, bytes memory _data, uint256 _gas) public returns (bytes32) {\n        return _sendMessage(_contract, _data, _gas, SEND_TO_MANUAL_LANE);\n    }\n\n    /**\n     * Parses given message, processes a call inside it\n     * @param _message relayed message\n     */\n    function handleMessage(bytes _message) internal {\n        bytes32 messageId;\n        address sender;\n        address executor;\n        uint32 gasLimit;\n        uint8 dataType;\n        uint256[2] memory chainIds;\n        bytes memory data;\n\n        (messageId, sender, executor, gasLimit, dataType, chainIds, data) = ArbitraryMessage.unpackData(_message);\n\n        require(_isMessageVersionValid(messageId));\n        require(_isDestinationChainIdValid(chainIds[1]));\n        processMessage(sender, executor, messageId, gasLimit, dataType, chainIds[0], data);\n    }\n\n    function submitSignature(bytes signature, bytes message) external onlyValidator {\n        // ensure that `signature` is really `message` signed by `msg.sender`\n        require(msg.sender == Message.recoverAddressFromSignedMessage(signature, message, true));\n        bytes32 hashMsg = keccak256(abi.encodePacked(message));\n        bytes32 hashSender = keccak256(abi.encodePacked(msg.sender, hashMsg));\n\n        uint256 signed = numMessagesSigned(hashMsg);\n        require(!isAlreadyProcessed(signed));\n        // the check above assumes that the case when the value could be overflew\n        // will not happen in the addition operation below\n        signed = signed + 1;\n        if (signed > 1) {\n            // Duplicated signatures\n            require(!messagesSigned(hashSender));\n        } else {\n            setMessages(hashMsg, message);\n        }\n        setMessagesSigned(hashSender, true);\n\n        bytes32 signIdx = keccak256(abi.encodePacked(hashMsg, (signed.sub(1))));\n        setSignatures(signIdx, signature);\n\n        setNumMessagesSigned(hashMsg, signed);\n\n        emit SignedForUserRequest(msg.sender, hashMsg);\n\n        uint256 reqSigs = requiredSignatures();\n        if (signed >= reqSigs) {\n            setNumMessagesSigned(hashMsg, markAsProcessed(signed));\n            emit CollectedSignatures(msg.sender, hashMsg, reqSigs);\n        }\n    }\n\n    function isAlreadyProcessed(uint256 _number) public pure returns (bool) {\n        return _number & (2**255) == 2**255;\n    }\n\n    function numMessagesSigned(bytes32 _message) public view returns (uint256) {\n        return uintStorage[keccak256(abi.encodePacked(\"numMessagesSigned\", _message))];\n    }\n\n    function signature(bytes32 _hash, uint256 _index) public view returns (bytes) {\n        bytes32 signIdx = keccak256(abi.encodePacked(_hash, _index));\n        return bytesStorage[keccak256(abi.encodePacked(\"signatures\", signIdx))];\n    }\n\n    function messagesSigned(bytes32 _message) public view returns (bool) {\n        return boolStorage[keccak256(abi.encodePacked(\"messagesSigned\", _message))];\n    }\n\n    function message(bytes32 _hash) public view returns (bytes) {\n        return messages(_hash);\n    }\n\n    function affirmationsSigned(bytes32 _hash) public view returns (bool) {\n        return boolStorage[keccak256(abi.encodePacked(\"affirmationsSigned\", _hash))];\n    }\n\n    function numAffirmationsSigned(bytes32 _hash) public view returns (uint256) {\n        return uintStorage[keccak256(abi.encodePacked(\"numAffirmationsSigned\", _hash))];\n    }\n\n    function setMessagesSigned(bytes32 _hash, bool _status) internal {\n        boolStorage[keccak256(abi.encodePacked(\"messagesSigned\", _hash))] = _status;\n    }\n\n    function messages(bytes32 _hash) internal view returns (bytes) {\n        return bytesStorage[keccak256(abi.encodePacked(\"messages\", _hash))];\n    }\n\n    function setSignatures(bytes32 _hash, bytes _signature) internal {\n        bytesStorage[keccak256(abi.encodePacked(\"signatures\", _hash))] = _signature;\n    }\n\n    function setMessages(bytes32 _hash, bytes _message) internal {\n        bytesStorage[keccak256(abi.encodePacked(\"messages\", _hash))] = _message;\n    }\n\n    function setNumMessagesSigned(bytes32 _message, uint256 _number) internal {\n        uintStorage[keccak256(abi.encodePacked(\"numMessagesSigned\", _message))] = _number;\n    }\n\n    function markAsProcessed(uint256 _v) internal pure returns (uint256) {\n        return _v | (2**255);\n    }\n\n    function setAffirmationsSigned(bytes32 _hash, bool _status) internal {\n        boolStorage[keccak256(abi.encodePacked(\"affirmationsSigned\", _hash))] = _status;\n    }\n\n    function setNumAffirmationsSigned(bytes32 _hash, uint256 _number) internal {\n        uintStorage[keccak256(abi.encodePacked(\"numAffirmationsSigned\", _hash))] = _number;\n    }\n}\n"
      },
      "contracts/libraries/ArbitraryMessage.sol": {
        "content": "pragma solidity 0.4.24;\n\nlibrary ArbitraryMessage {\n    /**\n    * @dev Unpacks data fields from AMB message\n    * layout of message :: bytes:\n    * offset  0              : 32 bytes :: uint256 - message length\n    * offset 32              : 32 bytes :: bytes32 - messageId\n    * offset 64              : 20 bytes :: address - sender address\n    * offset 84              : 20 bytes :: address - executor contract\n    * offset 104             : 4 bytes  :: uint32  - gasLimit\n    * offset 108             : 1 bytes  :: uint8   - source chain id length (X)\n    * offset 109             : 1 bytes  :: uint8   - destination chain id length (Y)\n    * offset 110             : 1 bytes  :: uint8   - dataType\n    * offset 111             : X bytes  :: bytes   - source chain id\n    * offset 111 + X         : Y bytes  :: bytes   - destination chain id\n\n    * NOTE: when message structure is changed, make sure that MESSAGE_PACKING_VERSION from VersionableAMB is updated as well\n    * NOTE: assembly code uses calldatacopy, make sure that message is passed as the first argument in the calldata\n    * @param _data encoded message\n    */\n    function unpackData(bytes _data)\n        internal\n        pure\n        returns (\n            bytes32 messageId,\n            address sender,\n            address executor,\n            uint32 gasLimit,\n            uint8 dataType,\n            uint256[2] chainIds,\n            bytes memory data\n        )\n    {\n        // 32 (message id) + 20 (sender) + 20 (executor) + 4 (gasLimit) + 1 (source chain id length) + 1 (destination chain id length) + 1 (dataType)\n        uint256 srcdataptr = 32 + 20 + 20 + 4 + 1 + 1 + 1;\n        uint256 datasize;\n\n        assembly {\n            messageId := mload(add(_data, 32)) // 32 bytes\n            sender := and(mload(add(_data, 52)), 0xffffffffffffffffffffffffffffffffffffffff) // 20 bytes\n\n            // executor (20 bytes) + gasLimit (4 bytes) + srcChainIdLength (1 byte) + dstChainIdLength (1 bytes) + dataType (1 byte) + remainder (5 bytes)\n            let blob := mload(add(_data, 84))\n\n            // after bit shift left 12 bytes are zeros automatically\n            executor := shr(96, blob)\n            gasLimit := and(shr(64, blob), 0xffffffff)\n\n            dataType := byte(26, blob)\n\n            // load source chain id length\n            let chainIdLength := byte(24, blob)\n\n            // at this moment srcdataptr points to sourceChainId\n\n            // mask for sourceChainId\n            // e.g. length X -> (1 << (X * 8)) - 1\n            let mask := sub(shl(shl(3, chainIdLength), 1), 1)\n\n            // increase payload offset by length of source chain id\n            srcdataptr := add(srcdataptr, chainIdLength)\n\n            // write sourceChainId\n            mstore(chainIds, and(mload(add(_data, srcdataptr)), mask))\n\n            // at this moment srcdataptr points to destinationChainId\n\n            // load destination chain id length\n            chainIdLength := byte(25, blob)\n\n            // mask for destinationChainId\n            // e.g. length X -> (1 << (X * 8)) - 1\n            mask := sub(shl(shl(3, chainIdLength), 1), 1)\n\n            // increase payload offset by length of destination chain id\n            srcdataptr := add(srcdataptr, chainIdLength)\n\n            // write destinationChainId\n            mstore(add(chainIds, 32), and(mload(add(_data, srcdataptr)), mask))\n\n            // at this moment srcdataptr points to payload\n\n            // datasize = message length - payload offset\n            datasize := sub(mload(_data), srcdataptr)\n        }\n\n        data = new bytes(datasize);\n        assembly {\n            // 36 = 4 (selector) + 32 (bytes length header)\n            srcdataptr := add(srcdataptr, 36)\n\n            // calldataload(4) - offset of first bytes argument in the calldata\n            calldatacopy(add(data, 32), add(calldataload(4), srcdataptr), datasize)\n        }\n    }\n}\n"
      },
      "contracts/libraries/Message.sol": {
        "content": "pragma solidity 0.4.24;\nimport \"../interfaces/IBridgeValidators.sol\";\n\nlibrary Message {\n    function addressArrayContains(address[] array, address value) internal pure returns (bool) {\n        for (uint256 i = 0; i < array.length; i++) {\n            if (array[i] == value) {\n                return true;\n            }\n        }\n        return false;\n    }\n    // layout of message :: bytes:\n    // offset  0: 32 bytes :: uint256 - message length\n    // offset 32: 20 bytes :: address - recipient address\n    // offset 52: 32 bytes :: uint256 - value\n    // offset 84: 32 bytes :: bytes32 - transaction hash\n    // offset 116: 20 bytes :: address - contract address to prevent double spending\n\n    // mload always reads 32 bytes.\n    // so we can and have to start reading recipient at offset 20 instead of 32.\n    // if we were to read at 32 the address would contain part of value and be corrupted.\n    // when reading from offset 20 mload will read 12 bytes (most of them zeros) followed\n    // by the 20 recipient address bytes and correctly convert it into an address.\n    // this saves some storage/gas over the alternative solution\n    // which is padding address to 32 bytes and reading recipient at offset 32.\n    // for more details see discussion in:\n    // https://github.com/paritytech/parity-bridge/issues/61\n    function parseMessage(bytes message)\n        internal\n        pure\n        returns (address recipient, uint256 amount, bytes32 txHash, address contractAddress)\n    {\n        require(isMessageValid(message));\n        assembly {\n            recipient := mload(add(message, 20))\n            amount := mload(add(message, 52))\n            txHash := mload(add(message, 84))\n            contractAddress := mload(add(message, 104))\n        }\n    }\n\n    function isMessageValid(bytes _msg) internal pure returns (bool) {\n        return _msg.length == requiredMessageLength();\n    }\n\n    function requiredMessageLength() internal pure returns (uint256) {\n        return 104;\n    }\n\n    function recoverAddressFromSignedMessage(bytes signature, bytes message, bool isAMBMessage)\n        internal\n        pure\n        returns (address)\n    {\n        require(signature.length == 65);\n        bytes32 r;\n        bytes32 s;\n        bytes1 v;\n\n        assembly {\n            r := mload(add(signature, 0x20))\n            s := mload(add(signature, 0x40))\n            v := mload(add(signature, 0x60))\n        }\n        require(uint8(v) == 27 || uint8(v) == 28);\n        require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0);\n\n        return ecrecover(hashMessage(message, isAMBMessage), uint8(v), r, s);\n    }\n\n    function hashMessage(bytes message, bool isAMBMessage) internal pure returns (bytes32) {\n        bytes memory prefix = \"\\x19Ethereum Signed Message:\\n\";\n        if (isAMBMessage) {\n            return keccak256(abi.encodePacked(prefix, uintToString(message.length), message));\n        } else {\n            string memory msgLength = \"104\";\n            return keccak256(abi.encodePacked(prefix, msgLength, message));\n        }\n    }\n\n    /**\n    * @dev Validates provided signatures, only first requiredSignatures() number\n    * of signatures are going to be validated, these signatures should be from different validators.\n    * @param _message bytes message used to generate signatures\n    * @param _signatures bytes blob with signatures to be validated.\n    * First byte X is a number of signatures in a blob,\n    * next X bytes are v components of signatures,\n    * next 32 * X bytes are r components of signatures,\n    * next 32 * X bytes are s components of signatures.\n    * @param _validatorContract contract, which conforms to the IBridgeValidators interface,\n    * where info about current validators and required signatures is stored.\n    * @param isAMBMessage true if _message is an AMB message with arbitrary length.\n    */\n    function hasEnoughValidSignatures(\n        bytes _message,\n        bytes _signatures,\n        IBridgeValidators _validatorContract,\n        bool isAMBMessage\n    ) internal view {\n        require(isAMBMessage || isMessageValid(_message));\n        uint256 requiredSignatures = _validatorContract.requiredSignatures();\n        uint256 amount;\n        assembly {\n            amount := and(mload(add(_signatures, 1)), 0xff)\n        }\n        require(amount >= requiredSignatures);\n        bytes32 hash = hashMessage(_message, isAMBMessage);\n        address[] memory encounteredAddresses = new address[](requiredSignatures);\n\n        for (uint256 i = 0; i < requiredSignatures; i++) {\n            uint8 v;\n            bytes32 r;\n            bytes32 s;\n            uint256 posr = 33 + amount + 32 * i;\n            uint256 poss = posr + 32 * amount;\n            assembly {\n                v := mload(add(_signatures, add(2, i)))\n                r := mload(add(_signatures, posr))\n                s := mload(add(_signatures, poss))\n            }\n\n            address recoveredAddress = ecrecover(hash, v, r, s);\n            require(_validatorContract.isValidator(recoveredAddress));\n            require(!addressArrayContains(encounteredAddresses, recoveredAddress));\n            encounteredAddresses[i] = recoveredAddress;\n        }\n    }\n\n    function uintToString(uint256 i) internal pure returns (string) {\n        if (i == 0) return \"0\";\n        uint256 j = i;\n        uint256 length;\n        while (j != 0) {\n            length++;\n            j /= 10;\n        }\n        bytes memory bstr = new bytes(length);\n        uint256 k = length - 1;\n        while (i != 0) {\n            bstr[k--] = bytes1(48 + (i % 10));\n            i /= 10;\n        }\n        return string(bstr);\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/arbitrary_message/BasicAMB.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../BasicBridge.sol\";\nimport \"./VersionableAMB.sol\";\n\ncontract BasicAMB is BasicBridge, VersionableAMB {\n    bytes32 internal constant MAX_GAS_PER_TX = 0x2670ecc91ec356e32067fd27b36614132d727b84a1e03e08f412a4f2cf075974; // keccak256(abi.encodePacked(\"maxGasPerTx\"))\n    bytes32 internal constant NONCE = 0x7ab1577440dd7bedf920cb6de2f9fc6bf7ba98c78c85a3fa1f8311aac95e1759; // keccak256(abi.encodePacked(\"nonce\"))\n    bytes32 internal constant SOURCE_CHAIN_ID = 0x67d6f42a1ed69c62022f2d160ddc6f2f0acd37ad1db0c24f4702d7d3343a4add; // keccak256(abi.encodePacked(\"sourceChainId\"))\n    bytes32 internal constant SOURCE_CHAIN_ID_LENGTH = 0xe504ae1fd6471eea80f18b8532a61a9bb91fba4f5b837f80a1cfb6752350af44; // keccak256(abi.encodePacked(\"sourceChainIdLength\"))\n    bytes32 internal constant DESTINATION_CHAIN_ID = 0xbbd454018e72a3f6c02bbd785bacc49e46292744f3f6761276723823aa332320; // keccak256(abi.encodePacked(\"destinationChainId\"))\n    bytes32 internal constant DESTINATION_CHAIN_ID_LENGTH = 0xfb792ae4ad11102b93f26a51b3749c2b3667f8b561566a4806d4989692811594; // keccak256(abi.encodePacked(\"destinationChainIdLength\"))\n    bytes32 internal constant ALLOW_REENTRANT_REQUESTS = 0xffa3a5a0e192028fc343362a39c5688e5a60819a4dc5ab3ee70c25bc25b78dd6; // keccak256(abi.encodePacked(\"allowReentrantRequests\"))\n\n    /**\n     * Initializes AMB contract\n     * @param _sourceChainId chain id of a network where this contract is deployed\n     * @param _destinationChainId chain id of a network where all outgoing messages are directed\n     * @param _validatorContract address of the validators contract\n     * @param _maxGasPerTx maximum amount of gas per one message execution\n     * @param _gasPrice default gas price used by oracles for sending transactions in this network\n     * @param _requiredBlockConfirmations number of block confirmations oracle will wait before processing passed messages\n     * @param _owner address of new bridge owner\n     */\n    function initialize(\n        uint256 _sourceChainId,\n        uint256 _destinationChainId,\n        address _validatorContract,\n        uint256 _maxGasPerTx,\n        uint256 _gasPrice,\n        uint256 _requiredBlockConfirmations,\n        address _owner\n    ) external onlyRelevantSender returns (bool) {\n        require(!isInitialized());\n        require(AddressUtils.isContract(_validatorContract));\n\n        _setChainIds(_sourceChainId, _destinationChainId);\n        addressStorage[VALIDATOR_CONTRACT] = _validatorContract;\n        uintStorage[DEPLOYED_AT_BLOCK] = block.number;\n        uintStorage[MAX_GAS_PER_TX] = _maxGasPerTx;\n        _setGasPrice(_gasPrice);\n        _setRequiredBlockConfirmations(_requiredBlockConfirmations);\n        _setOwner(_owner);\n        setInitialize();\n\n        return isInitialized();\n    }\n\n    function getBridgeMode() external pure returns (bytes4 _data) {\n        return 0x2544fbb9; // bytes4(keccak256(abi.encodePacked(\"arbitrary-message-bridge-core\")))\n    }\n\n    function maxGasPerTx() public view returns (uint256) {\n        return uintStorage[MAX_GAS_PER_TX];\n    }\n\n    function setMaxGasPerTx(uint256 _maxGasPerTx) external onlyOwner {\n        uintStorage[MAX_GAS_PER_TX] = _maxGasPerTx;\n    }\n\n    /**\n     * Internal function for retrieving chain id for the source network\n     * @return chain id for the current network\n     */\n    function sourceChainId() public view returns (uint256) {\n        return uintStorage[SOURCE_CHAIN_ID];\n    }\n\n    /**\n     * Internal function for retrieving chain id for the destination network\n     * @return chain id for the destination network\n     */\n    function destinationChainId() public view returns (uint256) {\n        return uintStorage[DESTINATION_CHAIN_ID];\n    }\n\n    /**\n     * Updates chain ids of used networks\n     * @param _sourceChainId chain id for current network\n     * @param _destinationChainId chain id for opposite network\n     */\n    function setChainIds(uint256 _sourceChainId, uint256 _destinationChainId) external onlyOwner {\n        _setChainIds(_sourceChainId, _destinationChainId);\n    }\n\n    /**\n     * Sets the flag to allow passing new AMB requests in the opposite direction,\n     * while other AMB message is being processed.\n     * Only owner can call this method.\n     * @param _enable true, if reentrant requests are allowed.\n     */\n    function setAllowReentrantRequests(bool _enable) external onlyOwner {\n        boolStorage[ALLOW_REENTRANT_REQUESTS] = _enable;\n    }\n\n    /**\n     * Tells if passing reentrant requests is allowed.\n     * @return true, if reentrant requests are allowed.\n     */\n    function allowReentrantRequests() public view returns (bool) {\n        return boolStorage[ALLOW_REENTRANT_REQUESTS];\n    }\n\n    /**\n     * @dev Withdraws the erc20 tokens or native coins from this contract.\n     * @param _token address of the claimed token or address(0) for native coins.\n     * @param _to address of the tokens/coins receiver.\n     */\n    function claimTokens(address _token, address _to) external onlyIfUpgradeabilityOwner {\n        claimValues(_token, _to);\n    }\n\n    /**\n     * Internal function for retrieving current nonce value\n     * @return nonce value\n     */\n    function _nonce() internal view returns (uint64) {\n        return uint64(uintStorage[NONCE]);\n    }\n\n    /**\n     * Internal function for updating nonce value\n     * @param _nonce new nonce value\n     */\n    function _setNonce(uint64 _nonce) internal {\n        uintStorage[NONCE] = uint256(_nonce);\n    }\n\n    /**\n     * Internal function for updating chain ids of used networks\n     * @param _sourceChainId chain id for current network\n     * @param _destinationChainId chain id for opposite network\n     */\n    function _setChainIds(uint256 _sourceChainId, uint256 _destinationChainId) internal {\n        require(_sourceChainId > 0 && _destinationChainId > 0);\n        require(_sourceChainId != _destinationChainId);\n\n        // Length fields are needed further when encoding the message.\n        // Chain ids are compressed, so that leading zero bytes are not preserved.\n        // In order to save some gas during calls to MessageDelivery.c,\n        // lengths of chain ids are precalculated and being saved in the storage.\n        uint256 sourceChainIdLength = 0;\n        uint256 destinationChainIdLength = 0;\n        uint256 mask = 0xff;\n\n        for (uint256 i = 1; sourceChainIdLength == 0 || destinationChainIdLength == 0; i++) {\n            if (sourceChainIdLength == 0 && _sourceChainId & mask == _sourceChainId) {\n                sourceChainIdLength = i;\n            }\n            if (destinationChainIdLength == 0 && _destinationChainId & mask == _destinationChainId) {\n                destinationChainIdLength = i;\n            }\n            mask = (mask << 8) | 0xff;\n        }\n\n        uintStorage[SOURCE_CHAIN_ID] = _sourceChainId;\n        uintStorage[SOURCE_CHAIN_ID_LENGTH] = sourceChainIdLength;\n        uintStorage[DESTINATION_CHAIN_ID] = _destinationChainId;\n        uintStorage[DESTINATION_CHAIN_ID_LENGTH] = destinationChainIdLength;\n    }\n\n    /**\n     * Internal function for retrieving chain id length for the source network\n     * @return chain id for the current network\n     */\n    function _sourceChainIdLength() internal view returns (uint256) {\n        return uintStorage[SOURCE_CHAIN_ID_LENGTH];\n    }\n\n    /**\n     * Internal function for retrieving chain id length for the destination network\n     * @return chain id for the destination network\n     */\n    function _destinationChainIdLength() internal view returns (uint256) {\n        return uintStorage[DESTINATION_CHAIN_ID_LENGTH];\n    }\n\n    /**\n     * Internal function for validating version of the received message\n     * @param _messageId id of the received message\n     */\n    function _isMessageVersionValid(bytes32 _messageId) internal returns (bool) {\n        return\n            _messageId & 0xffffffff00000000000000000000000000000000000000000000000000000000 == MESSAGE_PACKING_VERSION;\n    }\n\n    /**\n     * Internal function for validating destination chain id of the received message\n     * @param _chainId destination chain id of the received message\n     */\n    function _isDestinationChainIdValid(uint256 _chainId) internal returns (bool res) {\n        return _chainId == sourceChainId();\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/arbitrary_message/MessageDelivery.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"openzeppelin-solidity/contracts/math/SafeMath.sol\";\nimport \"./BasicAMB.sol\";\nimport \"./MessageProcessor.sol\";\nimport \"../../libraries/ArbitraryMessage.sol\";\nimport \"../../libraries/Bytes.sol\";\n\ncontract MessageDelivery is BasicAMB, MessageProcessor {\n    using SafeMath for uint256;\n\n    uint256 internal constant SEND_TO_ORACLE_DRIVEN_LANE = 0x00;\n    // after EIP2929, call to warmed contract address costs 100 instead of 2600\n    uint256 internal constant MIN_GAS_PER_CALL = 100;\n\n    /**\n    * @dev Requests message relay to the opposite network\n    * @param _contract executor address on the other side\n    * @param _data calldata passed to the executor on the other side\n    * @param _gas gas limit used on the other network for executing a message\n    */\n    function requireToPassMessage(address _contract, bytes memory _data, uint256 _gas) public returns (bytes32) {\n        return _sendMessage(_contract, _data, _gas, SEND_TO_ORACLE_DRIVEN_LANE);\n    }\n\n    /**\n    * @dev Initiates sending of an AMB message to the opposite network\n    * @param _contract executor address on the other side\n    * @param _data calldata passed to the executor on the other side\n    * @param _gas gas limit used on the other network for executing a message\n    * @param _dataType AMB message dataType to be included as a part of the header\n    */\n    function _sendMessage(address _contract, bytes memory _data, uint256 _gas, uint256 _dataType)\n        internal\n        returns (bytes32)\n    {\n        // it is not allowed to pass messages while other messages are processed\n        // if other is not explicitly configured\n        require(messageId() == bytes32(0) || allowReentrantRequests());\n        require(_gas >= MIN_GAS_PER_CALL && _gas <= maxGasPerTx());\n\n        uint256 selector;\n        assembly {\n            selector := and(mload(add(_data, 4)), 0xffffffff)\n        }\n        // In order to prevent possible unauthorized ERC20 withdrawals, the following function signatures are prohibited:\n        // * transfer(address,uint256)\n        // * approve(address,uint256)\n        // * transferFrom(address,address,uint256)\n        // * approveAndCall(address,uint256,bytes)\n        // * transferAndCall(address,uint256,bytes)\n        // See https://medium.com/immunefi/xdai-stake-arbitrary-call-method-bug-postmortem-f80a90ac56e3 for more details\n        require(\n            selector != 0xa9059cbb &&\n                selector != 0x095ea7b3 &&\n                selector != 0x23b872dd &&\n                selector != 0x4000aea0 &&\n                selector != 0xcae9ca51\n        );\n\n        (bytes32 _messageId, bytes memory header) = _packHeader(_contract, _gas, _dataType);\n\n        bytes memory eventData = abi.encodePacked(header, _data);\n\n        emitEventOnMessageRequest(_messageId, eventData);\n        return _messageId;\n    }\n\n    /**\n    * @dev Packs message header into a single bytes blob\n    * @param _contract executor address on the other side\n    * @param _gas gas limit used on the other network for executing a message\n    * @param _dataType AMB message dataType to be included as a part of the header\n    */\n    function _packHeader(address _contract, uint256 _gas, uint256 _dataType)\n        internal\n        view\n        returns (bytes32 _messageId, bytes memory header)\n    {\n        uint256 srcChainId = sourceChainId();\n        uint256 srcChainIdLength = _sourceChainIdLength();\n        uint256 dstChainId = destinationChainId();\n        uint256 dstChainIdLength = _destinationChainIdLength();\n\n        _messageId = _getNewMessageId(srcChainId);\n\n        // 79 = 4 + 20 + 8 + 20 + 20 + 4 + 1 + 1 + 1\n        header = new bytes(79 + srcChainIdLength + dstChainIdLength);\n\n        // In order to save the gas, the header is packed in the reverse order.\n        // With such approach, it is possible to store right-aligned values without any additional bit shifts.\n        assembly {\n            let ptr := add(header, mload(header)) // points to the last word of header\n            mstore(ptr, dstChainId)\n            mstore(sub(ptr, dstChainIdLength), srcChainId)\n\n            mstore(add(header, 79), _dataType)\n            mstore(add(header, 78), dstChainIdLength)\n            mstore(add(header, 77), srcChainIdLength)\n            mstore(add(header, 76), _gas)\n            mstore(add(header, 72), _contract)\n            mstore(add(header, 52), caller)\n            mstore(add(header, 32), _messageId)\n        }\n    }\n\n    /**\n     * @dev Generates a new messageId for the passed request/message.\n     * Increments the nonce accordingly.\n     * @param _srcChainId source chain id of the newly created message. Should be a chain id of the current network.\n     * @return unique message id to use for the new request/message.\n     */\n    function _getNewMessageId(uint256 _srcChainId) internal returns (bytes32) {\n        uint64 nonce = _nonce();\n        _setNonce(nonce + 1);\n\n        // Bridge id is recalculated every time again and again, since it is still cheaper than using SLOAD opcode (800 gas)\n        bytes32 bridgeId = keccak256(abi.encodePacked(_srcChainId, address(this))) &\n            0x00000000ffffffffffffffffffffffffffffffffffffffff0000000000000000;\n\n        return MESSAGE_PACKING_VERSION | bridgeId | bytes32(nonce);\n    }\n\n    /* solcov ignore next */\n    function emitEventOnMessageRequest(bytes32 messageId, bytes encodedData) internal;\n}\n"
      },
      "contracts/interfaces/IBridgeValidators.sol": {
        "content": "pragma solidity 0.4.24;\n\ninterface IBridgeValidators {\n    function isValidator(address _validator) external view returns (bool);\n    function requiredSignatures() external view returns (uint256);\n    function owner() external view returns (address);\n}\n"
      },
      "contracts/upgradeable_contracts/BasicBridge.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"./Upgradeable.sol\";\nimport \"./InitializableBridge.sol\";\nimport \"openzeppelin-solidity/contracts/AddressUtils.sol\";\nimport \"./Validatable.sol\";\nimport \"./Ownable.sol\";\nimport \"./Claimable.sol\";\nimport \"./VersionableBridge.sol\";\nimport \"./DecimalShiftBridge.sol\";\n\ncontract BasicBridge is\n    InitializableBridge,\n    Validatable,\n    Ownable,\n    Upgradeable,\n    Claimable,\n    VersionableBridge,\n    DecimalShiftBridge\n{\n    event GasPriceChanged(uint256 gasPrice);\n    event RequiredBlockConfirmationChanged(uint256 requiredBlockConfirmations);\n\n    bytes32 internal constant GAS_PRICE = 0x55b3774520b5993024893d303890baa4e84b1244a43c60034d1ced2d3cf2b04b; // keccak256(abi.encodePacked(\"gasPrice\"))\n    bytes32 internal constant REQUIRED_BLOCK_CONFIRMATIONS = 0x916daedf6915000ff68ced2f0b6773fe6f2582237f92c3c95bb4d79407230071; // keccak256(abi.encodePacked(\"requiredBlockConfirmations\"))\n\n    /**\n    * @dev Public setter for fallback gas price value. Only bridge owner can call this method.\n    * @param _gasPrice new value for the gas price.\n    */\n    function setGasPrice(uint256 _gasPrice) external onlyOwner {\n        _setGasPrice(_gasPrice);\n    }\n\n    function gasPrice() external view returns (uint256) {\n        return uintStorage[GAS_PRICE];\n    }\n\n    function setRequiredBlockConfirmations(uint256 _blockConfirmations) external onlyOwner {\n        _setRequiredBlockConfirmations(_blockConfirmations);\n    }\n\n    function _setRequiredBlockConfirmations(uint256 _blockConfirmations) internal {\n        require(_blockConfirmations > 0);\n        uintStorage[REQUIRED_BLOCK_CONFIRMATIONS] = _blockConfirmations;\n        emit RequiredBlockConfirmationChanged(_blockConfirmations);\n    }\n\n    function requiredBlockConfirmations() external view returns (uint256) {\n        return uintStorage[REQUIRED_BLOCK_CONFIRMATIONS];\n    }\n\n    /**\n    * @dev Internal function for updating fallback gas price value.\n    * @param _gasPrice new value for the gas price, zero gas price is allowed.\n    */\n    function _setGasPrice(uint256 _gasPrice) internal {\n        uintStorage[GAS_PRICE] = _gasPrice;\n        emit GasPriceChanged(_gasPrice);\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/arbitrary_message/VersionableAMB.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../VersionableBridge.sol\";\n\ncontract VersionableAMB is VersionableBridge {\n    // message format version as a single 4-bytes number padded to 32-bytes\n    // value, included into every outgoing relay request\n    //\n    // the message version should be updated every time when\n    // - new field appears\n    // - some field removed\n    // - fields order is changed\n    bytes32 internal constant MESSAGE_PACKING_VERSION = 0x00050000 << 224;\n\n    /**\n     * Returns currently used bridge version\n     * @return (major, minor, patch) version triple\n     */\n    function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) {\n        return (6, 2, 0);\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/InitializableBridge.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"./Initializable.sol\";\n\ncontract InitializableBridge is Initializable {\n    bytes32 internal constant DEPLOYED_AT_BLOCK = 0xb120ceec05576ad0c710bc6e85f1768535e27554458f05dcbb5c65b8c7a749b0; // keccak256(abi.encodePacked(\"deployedAtBlock\"))\n\n    function deployedAtBlock() external view returns (uint256) {\n        return uintStorage[DEPLOYED_AT_BLOCK];\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/Validatable.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../interfaces/IBridgeValidators.sol\";\nimport \"../upgradeability/EternalStorage.sol\";\nimport \"./ValidatorStorage.sol\";\n\ncontract Validatable is EternalStorage, ValidatorStorage {\n    function validatorContract() public view returns (IBridgeValidators) {\n        return IBridgeValidators(addressStorage[VALIDATOR_CONTRACT]);\n    }\n\n    modifier onlyValidator() {\n        require(validatorContract().isValidator(msg.sender));\n        /* solcov ignore next */\n        _;\n    }\n\n    function requiredSignatures() public view returns (uint256) {\n        return validatorContract().requiredSignatures();\n    }\n\n}\n"
      },
      "contracts/upgradeable_contracts/Ownable.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../upgradeability/EternalStorage.sol\";\nimport \"../interfaces/IUpgradeabilityOwnerStorage.sol\";\n\n/**\n * @title Ownable\n * @dev This contract has an owner address providing basic authorization control\n */\ncontract Ownable is EternalStorage {\n    bytes4 internal constant UPGRADEABILITY_OWNER = 0x6fde8202; // upgradeabilityOwner()\n\n    /**\n    * @dev Event to show ownership has been transferred\n    * @param previousOwner representing the address of the previous owner\n    * @param newOwner representing the address of the new owner\n    */\n    event OwnershipTransferred(address previousOwner, address newOwner);\n\n    /**\n    * @dev Throws if called by any account other than the owner.\n    */\n    modifier onlyOwner() {\n        require(msg.sender == owner());\n        /* solcov ignore next */\n        _;\n    }\n\n    /**\n    * @dev Throws if called by any account other than contract itself or owner.\n    */\n    modifier onlyRelevantSender() {\n        // proxy owner if used through proxy, address(0) otherwise\n        require(\n            !address(this).call(abi.encodeWithSelector(UPGRADEABILITY_OWNER)) || // covers usage without calling through storage proxy\n                msg.sender == IUpgradeabilityOwnerStorage(this).upgradeabilityOwner() || // covers usage through regular proxy calls\n                msg.sender == address(this) // covers calls through upgradeAndCall proxy method\n        );\n        /* solcov ignore next */\n        _;\n    }\n\n    bytes32 internal constant OWNER = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0; // keccak256(abi.encodePacked(\"owner\"))\n\n    /**\n    * @dev Tells the address of the owner\n    * @return the address of the owner\n    */\n    function owner() public view returns (address) {\n        return addressStorage[OWNER];\n    }\n\n    /**\n    * @dev Allows the current owner to transfer control of the contract to a newOwner.\n    * @param newOwner the address to transfer ownership to.\n    */\n    function transferOwnership(address newOwner) external onlyOwner {\n        _setOwner(newOwner);\n    }\n\n    /**\n    * @dev Sets a new owner address\n    */\n    function _setOwner(address newOwner) internal {\n        require(newOwner != address(0));\n        emit OwnershipTransferred(owner(), newOwner);\n        addressStorage[OWNER] = newOwner;\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/Upgradeable.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../interfaces/IUpgradeabilityOwnerStorage.sol\";\n\ncontract Upgradeable {\n    // Avoid using onlyUpgradeabilityOwner name to prevent issues with implementation from proxy contract\n    modifier onlyIfUpgradeabilityOwner() {\n        require(msg.sender == IUpgradeabilityOwnerStorage(this).upgradeabilityOwner());\n        /* solcov ignore next */\n        _;\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/Claimable.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../libraries/Address.sol\";\nimport \"../libraries/SafeERC20.sol\";\n\n/**\n * @title Claimable\n * @dev Implementation of the claiming utils that can be useful for withdrawing accidentally sent tokens that are not used in bridge operations.\n */\ncontract Claimable {\n    using SafeERC20 for address;\n\n    /**\n     * Throws if a given address is equal to address(0)\n     */\n    modifier validAddress(address _to) {\n        require(_to != address(0));\n        /* solcov ignore next */\n        _;\n    }\n\n    /**\n     * @dev Withdraws the erc20 tokens or native coins from this contract.\n     * Caller should additionally check that the claimed token is not a part of bridge operations (i.e. that token != erc20token()).\n     * @param _token address of the claimed token or address(0) for native coins.\n     * @param _to address of the tokens/coins receiver.\n     */\n    function claimValues(address _token, address _to) internal validAddress(_to) {\n        if (_token == address(0)) {\n            claimNativeCoins(_to);\n        } else {\n            claimErc20Tokens(_token, _to);\n        }\n    }\n\n    /**\n     * @dev Internal function for withdrawing all native coins from the contract.\n     * @param _to address of the coins receiver.\n     */\n    function claimNativeCoins(address _to) internal {\n        uint256 value = address(this).balance;\n        Address.safeSendValue(_to, value);\n    }\n\n    /**\n     * @dev Internal function for withdrawing all tokens of ssome particular ERC20 contract from this contract.\n     * @param _token address of the claimed ERC20 token.\n     * @param _to address of the tokens receiver.\n     */\n    function claimErc20Tokens(address _token, address _to) internal {\n        ERC20Basic token = ERC20Basic(_token);\n        uint256 balance = token.balanceOf(this);\n        _token.safeTransfer(_to, balance);\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/VersionableBridge.sol": {
        "content": "pragma solidity 0.4.24;\n\ncontract VersionableBridge {\n    function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) {\n        return (6, 1, 0);\n    }\n\n    /* solcov ignore next */\n    function getBridgeMode() external pure returns (bytes4);\n}\n"
      },
      "contracts/upgradeable_contracts/DecimalShiftBridge.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../upgradeability/EternalStorage.sol\";\nimport \"openzeppelin-solidity/contracts/math/SafeMath.sol\";\n\ncontract DecimalShiftBridge is EternalStorage {\n    using SafeMath for uint256;\n\n    bytes32 internal constant DECIMAL_SHIFT = 0x1e8ecaafaddea96ed9ac6d2642dcdfe1bebe58a930b1085842d8fc122b371ee5; // keccak256(abi.encodePacked(\"decimalShift\"))\n\n    /**\n    * @dev Internal function for setting the decimal shift for bridge operations.\n    * Decimal shift can be positive, negative, or equal to zero.\n    * It has the following meaning: N tokens in the foreign chain are equivalent to N * pow(10, shift) tokens on the home side.\n    * @param _shift new value of decimal shift.\n    */\n    function _setDecimalShift(int256 _shift) internal {\n        // since 1 wei * 10**77 > 2**255, it does not make any sense to use higher values\n        require(_shift > -77 && _shift < 77);\n        uintStorage[DECIMAL_SHIFT] = uint256(_shift);\n    }\n\n    /**\n    * @dev Returns the value of foreign-to-home decimal shift.\n    * @return decimal shift.\n    */\n    function decimalShift() public view returns (int256) {\n        return int256(uintStorage[DECIMAL_SHIFT]);\n    }\n\n    /**\n    * @dev Converts the amount of home tokens into the equivalent amount of foreign tokens.\n    * @param _value amount of home tokens.\n    * @return equivalent amount of foreign tokens.\n    */\n    function _unshiftValue(uint256 _value) internal view returns (uint256) {\n        return _shiftUint(_value, -decimalShift());\n    }\n\n    /**\n    * @dev Converts the amount of foreign tokens into the equivalent amount of home tokens.\n    * @param _value amount of foreign tokens.\n    * @return equivalent amount of home tokens.\n    */\n    function _shiftValue(uint256 _value) internal view returns (uint256) {\n        return _shiftUint(_value, decimalShift());\n    }\n\n    /**\n    * @dev Calculates _value * pow(10, _shift).\n    * @param _value amount of tokens.\n    * @param _shift decimal shift to apply.\n    * @return shifted value.\n    */\n    function _shiftUint(uint256 _value, int256 _shift) private pure returns (uint256) {\n        if (_shift == 0) {\n            return _value;\n        }\n        if (_shift > 0) {\n            return _value.mul(10**uint256(_shift));\n        }\n        return _value.div(10**uint256(-_shift));\n    }\n}\n"
      },
      "openzeppelin-solidity/contracts/AddressUtils.sol": {
        "content": "pragma solidity ^0.4.24;\n\n\n/**\n * Utility library of inline functions on addresses\n */\nlibrary AddressUtils {\n\n  /**\n   * Returns whether the target address is a contract\n   * @dev This function will return false if invoked during the constructor of a contract,\n   * as the code is not actually created until after the constructor finishes.\n   * @param _addr address to check\n   * @return whether the target address is a contract\n   */\n  function isContract(address _addr) internal view returns (bool) {\n    uint256 size;\n    // XXX Currently there is no better way to check if there is a contract in an address\n    // than to check the size of the code at that address.\n    // See https://ethereum.stackexchange.com/a/14016/36603\n    // for more details about how this works.\n    // TODO Check this again before the Serenity release, because all addresses will be\n    // contracts then.\n    // solium-disable-next-line security/no-inline-assembly\n    assembly { size := extcodesize(_addr) }\n    return size > 0;\n  }\n\n}\n"
      },
      "contracts/upgradeable_contracts/Initializable.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../upgradeability/EternalStorage.sol\";\n\ncontract Initializable is EternalStorage {\n    bytes32 internal constant INITIALIZED = 0x0a6f646cd611241d8073675e00d1a1ff700fbf1b53fcf473de56d1e6e4b714ba; // keccak256(abi.encodePacked(\"isInitialized\"))\n\n    function setInitialize() internal {\n        boolStorage[INITIALIZED] = true;\n    }\n\n    function isInitialized() public view returns (bool) {\n        return boolStorage[INITIALIZED];\n    }\n}\n"
      },
      "contracts/upgradeability/EternalStorage.sol": {
        "content": "pragma solidity 0.4.24;\n\n/**\n * @title EternalStorage\n * @dev This contract holds all the necessary state variables to carry out the storage of any contract.\n */\ncontract EternalStorage {\n    mapping(bytes32 => uint256) internal uintStorage;\n    mapping(bytes32 => string) internal stringStorage;\n    mapping(bytes32 => address) internal addressStorage;\n    mapping(bytes32 => bytes) internal bytesStorage;\n    mapping(bytes32 => bool) internal boolStorage;\n    mapping(bytes32 => int256) internal intStorage;\n\n}\n"
      },
      "contracts/upgradeable_contracts/ValidatorStorage.sol": {
        "content": "pragma solidity 0.4.24;\n\ncontract ValidatorStorage {\n    bytes32 internal constant VALIDATOR_CONTRACT = 0x5a74bb7e202fb8e4bf311841c7d64ec19df195fee77d7e7ae749b27921b6ddfe; // keccak256(abi.encodePacked(\"validatorContract\"))\n}\n"
      },
      "contracts/interfaces/IUpgradeabilityOwnerStorage.sol": {
        "content": "pragma solidity 0.4.24;\n\ninterface IUpgradeabilityOwnerStorage {\n    function upgradeabilityOwner() external view returns (address);\n}\n"
      },
      "contracts/libraries/Address.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../upgradeable_contracts/Sacrifice.sol\";\n\n/**\n * @title Address\n * @dev Helper methods for Address type.\n */\nlibrary Address {\n    /**\n    * @dev Try to send native tokens to the address. If it fails, it will force the transfer by creating a selfdestruct contract\n    * @param _receiver address that will receive the native tokens\n    * @param _value the amount of native tokens to send\n    */\n    function safeSendValue(address _receiver, uint256 _value) internal {\n        if (!_receiver.send(_value)) {\n            (new Sacrifice).value(_value)(_receiver);\n        }\n    }\n}\n"
      },
      "contracts/libraries/SafeERC20.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"openzeppelin-solidity/contracts/math/SafeMath.sol\";\nimport \"../interfaces/ERC677.sol\";\n\n/**\n * @title SafeERC20\n * @dev Helper methods for safe token transfers.\n * Functions perform additional checks to be sure that token transfer really happened.\n */\nlibrary SafeERC20 {\n    using SafeMath for uint256;\n\n    /**\n    * @dev Same as ERC20.transfer(address,uint256) but with extra consistency checks.\n    * @param _token address of the token contract\n    * @param _to address of the receiver\n    * @param _value amount of tokens to send\n    */\n    function safeTransfer(address _token, address _to, uint256 _value) internal {\n        LegacyERC20(_token).transfer(_to, _value);\n        assembly {\n            if returndatasize {\n                returndatacopy(0, 0, 32)\n                if iszero(mload(0)) {\n                    revert(0, 0)\n                }\n            }\n        }\n    }\n\n    /**\n    * @dev Same as ERC20.transferFrom(address,address,uint256) but with extra consistency checks.\n    * @param _token address of the token contract\n    * @param _from address of the sender\n    * @param _value amount of tokens to send\n    */\n    function safeTransferFrom(address _token, address _from, uint256 _value) internal {\n        LegacyERC20(_token).transferFrom(_from, address(this), _value);\n        assembly {\n            if returndatasize {\n                returndatacopy(0, 0, 32)\n                if iszero(mload(0)) {\n                    revert(0, 0)\n                }\n            }\n        }\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/Sacrifice.sol": {
        "content": "pragma solidity 0.4.24;\n\ncontract Sacrifice {\n    constructor(address _recipient) public payable {\n        selfdestruct(_recipient);\n    }\n}\n"
      },
      "openzeppelin-solidity/contracts/math/SafeMath.sol": {
        "content": "pragma solidity ^0.4.24;\n\n\n/**\n * @title SafeMath\n * @dev Math operations with safety checks that throw on error\n */\nlibrary SafeMath {\n\n  /**\n  * @dev Multiplies two numbers, throws on overflow.\n  */\n  function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {\n    // Gas optimization: this is cheaper than asserting 'a' not being zero, but the\n    // benefit is lost if 'b' is also tested.\n    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n    if (_a == 0) {\n      return 0;\n    }\n\n    c = _a * _b;\n    assert(c / _a == _b);\n    return c;\n  }\n\n  /**\n  * @dev Integer division of two numbers, truncating the quotient.\n  */\n  function div(uint256 _a, uint256 _b) internal pure returns (uint256) {\n    // assert(_b > 0); // Solidity automatically throws when dividing by 0\n    // uint256 c = _a / _b;\n    // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold\n    return _a / _b;\n  }\n\n  /**\n  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).\n  */\n  function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {\n    assert(_b <= _a);\n    return _a - _b;\n  }\n\n  /**\n  * @dev Adds two numbers, throws on overflow.\n  */\n  function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {\n    c = _a + _b;\n    assert(c >= _a);\n    return c;\n  }\n}\n"
      },
      "contracts/interfaces/ERC677.sol": {
        "content": "pragma solidity 0.4.24;\nimport \"openzeppelin-solidity/contracts/token/ERC20/ERC20.sol\";\n\ncontract ERC677 is ERC20 {\n    event Transfer(address indexed from, address indexed to, uint256 value, bytes data);\n\n    function transferAndCall(address, uint256, bytes) external returns (bool);\n\n    function increaseAllowance(address spender, uint256 addedValue) public returns (bool);\n    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool);\n}\n\ncontract LegacyERC20 {\n    function transfer(address _spender, uint256 _value) public; // returns (bool);\n    function transferFrom(address _owner, address _spender, uint256 _value) public; // returns (bool);\n}\n"
      },
      "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol": {
        "content": "pragma solidity ^0.4.24;\n\nimport \"./ERC20Basic.sol\";\n\n\n/**\n * @title ERC20 interface\n * @dev see https://github.com/ethereum/EIPs/issues/20\n */\ncontract ERC20 is ERC20Basic {\n  function allowance(address _owner, address _spender)\n    public view returns (uint256);\n\n  function transferFrom(address _from, address _to, uint256 _value)\n    public returns (bool);\n\n  function approve(address _spender, uint256 _value) public returns (bool);\n  event Approval(\n    address indexed owner,\n    address indexed spender,\n    uint256 value\n  );\n}\n"
      },
      "openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol": {
        "content": "pragma solidity ^0.4.24;\n\n\n/**\n * @title ERC20Basic\n * @dev Simpler version of ERC20 interface\n * See https://github.com/ethereum/EIPs/issues/179\n */\ncontract ERC20Basic {\n  function totalSupply() public view returns (uint256);\n  function balanceOf(address _who) public view returns (uint256);\n  function transfer(address _to, uint256 _value) public returns (bool);\n  event Transfer(address indexed from, address indexed to, uint256 value);\n}\n"
      },
      "contracts/libraries/Bytes.sol": {
        "content": "pragma solidity 0.4.24;\n\n/**\n * @title Bytes\n * @dev Helper methods to transform bytes to other solidity types.\n */\nlibrary Bytes {\n    /**\n    * @dev Converts bytes array to bytes32.\n    * Truncates bytes array if its size is more than 32 bytes.\n    * NOTE: This function does not perform any checks on the received parameter.\n    * Make sure that the _bytes argument has a correct length, not less than 32 bytes.\n    * A case when _bytes has length less than 32 will lead to the undefined behaviour,\n    * since assembly will read data from memory that is not related to the _bytes argument.\n    * @param _bytes to be converted to bytes32 type\n    * @return bytes32 type of the firsts 32 bytes array in parameter.\n    */\n    function bytesToBytes32(bytes _bytes) internal pure returns (bytes32 result) {\n        assembly {\n            result := mload(add(_bytes, 32))\n        }\n    }\n\n    /**\n    * @dev Truncate bytes array if its size is more than 20 bytes.\n    * NOTE: Similar to the bytesToBytes32 function, make sure that _bytes is not shorter than 20 bytes.\n    * @param _bytes to be converted to address type\n    * @return address included in the firsts 20 bytes of the bytes array in parameter.\n    */\n    function bytesToAddress(bytes _bytes) internal pure returns (address addr) {\n        assembly {\n            addr := mload(add(_bytes, 20))\n        }\n    }\n}\n"
      },
      "contracts/upgradeable_contracts/arbitrary_message/MessageProcessor.sol": {
        "content": "pragma solidity 0.4.24;\n\nimport \"../../upgradeability/EternalStorage.sol\";\nimport \"../../libraries/Bytes.sol\";\n\ncontract MessageProcessor is EternalStorage {\n    /**\n    * @dev Returns a status of the message that came from the other side.\n    * @param _messageId id of the message from the other side that triggered a call.\n    * @return true if call executed successfully.\n    */\n    function messageCallStatus(bytes32 _messageId) external view returns (bool) {\n        return boolStorage[keccak256(abi.encodePacked(\"messageCallStatus\", _messageId))];\n    }\n\n    /**\n    * @dev Sets a status of the message that came from the other side.\n    * @param _messageId id of the message from the other side that triggered a call.\n    * @param _status execution status, true if executed successfully.\n    */\n    function setMessageCallStatus(bytes32 _messageId, bool _status) internal {\n        boolStorage[keccak256(abi.encodePacked(\"messageCallStatus\", _messageId))] = _status;\n    }\n\n    /**\n    * @dev Returns a data hash of the failed message that came from the other side.\n    * NOTE: dataHash was used previously to identify outgoing message before AMB message id was introduced.\n    * It is kept for backwards compatibility with old mediators contracts.\n    * @param _messageId id of the message from the other side that triggered a call.\n    * @return keccak256 hash of message data.\n    */\n    function failedMessageDataHash(bytes32 _messageId) external view returns (bytes32) {\n        return bytes32(uintStorage[keccak256(abi.encodePacked(\"failedMessageDataHash\", _messageId))]);\n    }\n\n    /**\n    * @dev Sets a data hash of the failed message that came from the other side.\n    * NOTE: dataHash was used previously to identify outgoing message before AMB message id was introduced.\n    * It is kept for backwards compatibility with old mediators contracts.\n    * @param _messageId id of the message from the other side that triggered a call.\n    * @param data of the processed message.\n    */\n    function setFailedMessageDataHash(bytes32 _messageId, bytes data) internal {\n        uintStorage[keccak256(abi.encodePacked(\"failedMessageDataHash\", _messageId))] = uint256(keccak256(data));\n    }\n\n    /**\n    * @dev Returns a receiver address of the failed message that came from the other side.\n    * @param _messageId id of the message from the other side that triggered a call.\n    * @return receiver address.\n    */\n    function failedMessageReceiver(bytes32 _messageId) external view returns (address) {\n        return addressStorage[keccak256(abi.encodePacked(\"failedMessageReceiver\", _messageId))];\n    }\n\n    /**\n    * @dev Sets a sender address of the failed message that came from the other side.\n    * @param _messageId id of the message from the other side that triggered a call.\n    * @param _receiver address of the receiver.\n    */\n    function setFailedMessageReceiver(bytes32 _messageId, address _receiver) internal {\n        addressStorage[keccak256(abi.encodePacked(\"failedMessageReceiver\", _messageId))] = _receiver;\n    }\n\n    /**\n    * @dev Returns a sender address of the failed message that came from the other side.\n    * @param _messageId id of the message from the other side that triggered a call.\n    * @return sender address on the other side.\n    */\n    function failedMessageSender(bytes32 _messageId) external view returns (address) {\n        return addressStorage[keccak256(abi.encodePacked(\"failedMessageSender\", _messageId))];\n    }\n\n    /**\n    * @dev Sets a sender address of the failed message that came from the other side.\n    * @param _messageId id of the message from the other side that triggered a call.\n    * @param _sender address of the sender on the other side.\n    */\n    function setFailedMessageSender(bytes32 _messageId, address _sender) internal {\n        addressStorage[keccak256(abi.encodePacked(\"failedMessageSender\", _messageId))] = _sender;\n    }\n\n    /**\n    * @dev Returns an address of the sender on the other side for the currently processed message.\n    * Can be used by executors for getting other side caller address.\n    * @return address of the sender on the other side.\n    */\n    function messageSender() external view returns (address sender) {\n        assembly {\n            // Even though this is not the same as addressStorage[keccak256(abi.encodePacked(\"messageSender\"))],\n            // since solidity mapping introduces another level of addressing, such slot change is safe\n            // for temporary variables which are cleared at the end of the call execution.\n            sender := sload(0x7b58b2a669d8e0992eae9eaef641092c0f686fd31070e7236865557fa1571b5b) // keccak256(abi.encodePacked(\"messageSender\"))\n        }\n    }\n\n    /**\n    * @dev Sets an address of the sender on the other side for the currently processed message.\n    * @param _sender address of the sender on the other side.\n    */\n    function setMessageSender(address _sender) internal {\n        assembly {\n            // Even though this is not the same as addressStorage[keccak256(abi.encodePacked(\"messageSender\"))],\n            // since solidity mapping introduces another level of addressing, such slot change is safe\n            // for temporary variables which are cleared at the end of the call execution.\n            sstore(0x7b58b2a669d8e0992eae9eaef641092c0f686fd31070e7236865557fa1571b5b, _sender) // keccak256(abi.encodePacked(\"messageSender\"))\n        }\n    }\n\n    /**\n    * @dev Returns an id of the currently processed message.\n    * @return id of the message that originated on the other side.\n    */\n    function messageId() public view returns (bytes32 id) {\n        assembly {\n            // Even though this is not the same as uintStorage[keccak256(abi.encodePacked(\"messageId\"))],\n            // since solidity mapping introduces another level of addressing, such slot change is safe\n            // for temporary variables which are cleared at the end of the call execution.\n            id := sload(0xe34bb2103dc34f2c144cc216c132d6ffb55dac57575c22e089161bbe65083304) // keccak256(abi.encodePacked(\"messageId\"))\n        }\n    }\n\n    /**\n    * @dev Returns an id of the currently processed message.\n    * NOTE: transactionHash was used previously to identify incoming message before AMB message id was introduced.\n    * It is kept for backwards compatibility with old mediators contracts, although it doesn't return txHash anymore.\n    * @return id of the message that originated on the other side.\n    */\n    function transactionHash() external view returns (bytes32) {\n        return messageId();\n    }\n\n    /**\n    * @dev Sets a message id of the currently processed message.\n    * @param _messageId id of the message that originated on the other side.\n    */\n    function setMessageId(bytes32 _messageId) internal {\n        assembly {\n            // Even though this is not the same as uintStorage[keccak256(abi.encodePacked(\"messageId\"))],\n            // since solidity mapping introduces another level of addressing, such slot change is safe\n            // for temporary variables which are cleared at the end of the call execution.\n            sstore(0xe34bb2103dc34f2c144cc216c132d6ffb55dac57575c22e089161bbe65083304, _messageId) // keccak256(abi.encodePacked(\"messageId\"))\n        }\n    }\n\n    /**\n    * @dev Returns an originating chain id of the currently processed message.\n    * @return source chain id of the message that originated on the other side.\n    */\n    function messageSourceChainId() external view returns (uint256 id) {\n        assembly {\n            // Even though this is not the same as uintStorage[keccak256(abi.encodePacked(\"messageSourceChainId\"))],\n            // since solidity mapping introduces another level of addressing, such slot change is safe\n            // for temporary variables which are cleared at the end of the call execution.\n            id := sload(0x7f0fcd9e49860f055dd0c1682d635d309ecb5e3011654c716d9eb59a7ddec7d2) // keccak256(abi.encodePacked(\"messageSourceChainId\"))\n        }\n    }\n\n    /**\n    * @dev Sets an originating chain id of the currently processed message.\n    * @param _sourceChainId source chain id of the message that originated on the other side.\n    */\n    function setMessageSourceChainId(uint256 _sourceChainId) internal {\n        assembly {\n            // Even though this is not the same as uintStorage[keccak256(abi.encodePacked(\"messageSourceChainId\"))],\n            // since solidity mapping introduces another level of addressing, such slot change is safe\n            // for temporary variables which are cleared at the end of the call execution.\n            sstore(0x7f0fcd9e49860f055dd0c1682d635d309ecb5e3011654c716d9eb59a7ddec7d2, _sourceChainId) // keccak256(abi.encodePacked(\"messageSourceChainId\"))\n        }\n    }\n\n    /**\n    * @dev Processes received message. Makes a call to the message executor,\n    * sets dataHash, receive, sender variables for failed messages.\n    * @param _sender sender address on the other side.\n    * @param _executor address of an executor.\n    * @param _messageId id of the processed message.\n    * @param _gasLimit gas limit for a call to executor.\n    * @param _sourceChainId source chain id is of the received message.\n    * @param _data calldata for a call to executor.\n    */\n    function processMessage(\n        address _sender,\n        address _executor,\n        bytes32 _messageId,\n        uint256 _gasLimit,\n        uint8, /* dataType */\n        uint256 _sourceChainId,\n        bytes memory _data\n    ) internal {\n        bool status = _passMessage(_sender, _executor, _data, _gasLimit, _messageId, _sourceChainId);\n\n        setMessageCallStatus(_messageId, status);\n        if (!status) {\n            setFailedMessageDataHash(_messageId, _data);\n            setFailedMessageReceiver(_messageId, _executor);\n            setFailedMessageSender(_messageId, _sender);\n        }\n        emitEventOnMessageProcessed(_sender, _executor, _messageId, status);\n    }\n\n    /**\n    * @dev Makes a call to the message executor.\n    * @param _sender sender address on the other side.\n    * @param _contract address of an executor contract.\n    * @param _data calldata for a call to executor.\n    * @param _gas gas limit for a call to executor. 2^32 - 1, if caller will pass all available gas for the execution.\n    * @param _messageId id of the processed message.\n    * @param _sourceChainId source chain id is of the received message.\n    */\n    function _passMessage(\n        address _sender,\n        address _contract,\n        bytes _data,\n        uint256 _gas,\n        bytes32 _messageId,\n        uint256 _sourceChainId\n    ) internal returns (bool) {\n        setMessageSender(_sender);\n        setMessageId(_messageId);\n        setMessageSourceChainId(_sourceChainId);\n\n        // After EIP-150, max gas cost allowed to be passed to the internal call is equal to the 63/64 of total gas left.\n        // In reality, min(gasLimit, 63/64 * gasleft()) will be used as the call gas limit.\n        // Imagine a situation, when message requires 10000000 gas to be executed successfully.\n        // Also suppose, that at this point, gasleft() is equal to 10158000, so the callee will receive ~ 10158000 * 63 / 64 = 9999300 gas.\n        // That amount of gas is not enough, so the call will fail. At the same time,\n        // even if the callee failed the bridge contract still has ~ 158000 gas to\n        // finish its execution and it will be enough. The internal call fails but\n        // only because the oracle provides incorrect gas limit for the transaction\n        // This check is needed here in order to force contract to pass exactly the requested amount of gas.\n        // Avoiding it may lead to the unwanted message failure in some extreme cases.\n        require(_gas == 0xffffffff || (gasleft() * 63) / 64 > _gas);\n\n        bool status = _contract.call.gas(_gas)(_data);\n        _validateExecutionStatus(status);\n        setMessageSender(address(0));\n        setMessageId(bytes32(0));\n        setMessageSourceChainId(0);\n        return status;\n    }\n\n    /**\n    * @dev Validates message execution status. In simplest case, does nothing.\n    * @param _status message execution status.\n    */\n    function _validateExecutionStatus(bool _status) internal {\n        (_status);\n    }\n\n    /* solcov ignore next */\n    function emitEventOnMessageProcessed(address sender, address executor, bytes32 messageId, bool status) internal;\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}