ETH Price: $1,785.76 (+9.65%)
 

Overview

ETH Balance

4.462000000000000474 ETH

Eth Value

$7,968.06 (@ $1,785.76/ETH)

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Receive Message223309282025-04-23 9:53:1112 mins ago1745401991IN
0x110fd9a4...03F0020e4
0.0004 ETH0.00065491.78495442
Receive Message223309152025-04-23 9:50:3515 mins ago1745401835IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000568751.55554248
Receive Message223307302025-04-23 9:13:2352 mins ago1745399603IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000650911.79365648
Receive Message223305432025-04-23 8:35:111 hr ago1745397311IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000892562.34761234
Receive Message223299982025-04-23 6:45:113 hrs ago1745390711IN
0x110fd9a4...03F0020e4
0.0004 ETH0.001121992.93933506
Receive Message223299832025-04-23 6:42:113 hrs ago1745390531IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000725022.07614035
Receive Message223298092025-04-23 6:06:593 hrs ago1745388419IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000890092.3928188
Receive Message223297992025-04-23 6:04:594 hrs ago1745388299IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000646781.68799861
Receive Message223297642025-04-23 5:57:594 hrs ago1745387879IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000585431.52491038
Receive Message223297002025-04-23 5:45:114 hrs ago1745387111IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000671721.75136532
Receive Message223296882025-04-23 5:42:474 hrs ago1745386967IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000654751.78916886
Receive Message223296702025-04-23 5:39:114 hrs ago1745386751IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000740721.92893849
Receive Message223296472025-04-23 5:34:354 hrs ago1745386475IN
0x110fd9a4...03F0020e4
0.0004 ETH0.00085062.20969465
Receive Message223296072025-04-23 5:26:354 hrs ago1745385995IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000719511.87359329
Receive Message223293692025-04-23 4:38:115 hrs ago1745383091IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000389511.02301908
Receive Message223291512025-04-23 3:54:356 hrs ago1745380475IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000466591.21500018
Receive Message223291072025-04-23 3:45:236 hrs ago1745379923IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000450621.18204325
Receive Message223290192025-04-23 3:27:476 hrs ago1745378867IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000435441.13650221
Receive Message223287942025-04-23 2:42:237 hrs ago1745376143IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000642141.67475261
Receive Message223283842025-04-23 1:18:598 hrs ago1745371139IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000618851.60806486
Receive Message223277692025-04-22 23:15:3510 hrs ago1745363735IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000859422.43194047
Receive Message223276992025-04-22 23:01:3511 hrs ago1745362895IN
0x110fd9a4...03F0020e4
0.0004 ETH0.000506171.39136689
Receive Message223275162025-04-22 22:24:4711 hrs ago1745360687IN
0x110fd9a4...03F0020e4
0.0004 ETH0.001355933.75497258
Receive Message223274512025-04-22 22:11:3511 hrs ago1745359895IN
0x110fd9a4...03F0020e4
0.0004 ETH0.001564734.47370053
Receive Message223274392025-04-22 22:09:1111 hrs ago1745359751IN
0x110fd9a4...03F0020e4
0.0004 ETH0.001504623.91005105
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Send Message223309712025-04-23 10:01:474 mins ago1745402507
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223307872025-04-23 9:24:4741 mins ago1745400287
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223306852025-04-23 9:04:231 hr ago1745399063
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223305022025-04-23 8:26:591 hr ago1745396819
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223302182025-04-23 7:29:592 hrs ago1745393399
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223301212025-04-23 7:10:112 hrs ago1745392211
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223298432025-04-23 6:13:473 hrs ago1745388827
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223296472025-04-23 5:34:354 hrs ago1745386475
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223295202025-04-23 5:08:354 hrs ago1745384915
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223284452025-04-23 1:31:118 hrs ago1745371871
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223281272025-04-23 0:27:359 hrs ago1745368055
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223279902025-04-23 0:00:1110 hrs ago1745366411
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223275712025-04-22 22:35:5911 hrs ago1745361359
0x110fd9a4...03F0020e4
0.0003 ETH
Transfer223274092025-04-22 22:02:5912 hrs ago1745359379
0x110fd9a4...03F0020e4
0.012 ETH
Send Message223271162025-04-22 21:04:1113 hrs ago1745355851
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223263772025-04-22 18:35:3515 hrs ago1745346935
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223263052025-04-22 18:21:1115 hrs ago1745346071
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223263002025-04-22 18:20:1115 hrs ago1745346011
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223256862025-04-22 16:17:2317 hrs ago1745338643
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223253942025-04-22 15:18:4718 hrs ago1745335127
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223252492025-04-22 14:49:4719 hrs ago1745333387
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223239162025-04-22 10:22:1123 hrs ago1745317331
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223236962025-04-22 9:38:1124 hrs ago1745314691
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223234742025-04-22 8:53:3525 hrs ago1745312015
0x110fd9a4...03F0020e4
0.0003 ETH
Send Message223229912025-04-22 7:16:4726 hrs ago1745306207
0x110fd9a4...03F0020e4
0.0003 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Bridge

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 10 : Bridge.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.17;

import "@openzeppelin/contracts/utils/math/Math.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "./IBridge.sol";

/// @title Root network bridge contract on ethereum
/// @author Root Network
/// @notice Provides methods for verifying messages from the validator set
contract Bridge is IBridge, IBridgeReceiver, Ownable, ReentrancyGuard, ERC165 {
    using ECDSA for bytes32;

    // map from validator set nonce to keccak256 digest of validator ECDSA addresses (i.e bridge session keys)
    // these should be encoded in sorted order matching `pallet_session::Module<T>::validators()` to create the digest
    // signatures from a threshold of these addresses are considered approved by the protocol
    mapping(uint => bytes32) public validatorSetDigests;
    // Nonce for validator set changes
    uint32 public activeValidatorSetId;
    // Nonce of the next outgoing event
    uint public sentEventId;
    // Map of verified incoming event nonces
    // will only validate one event per nonce.
    // Verification/submission out of order is ok.
    mapping(uint => bool) public verifiedEventIds;
    // Fee for message verification
    // Offsets bridge upkeep costs i.e updating the validator set
    uint public bridgeFee = 4e15; // 0.004 ether
    // Acceptance threshold in %
    uint public thresholdPercent = 60;
    // Number of staking eras before a bridge message will be considered expired
    uint public proofTTL = 7;
    // Whether the bridge is active or not
    bool public active = false;
    // Max reward paid out to successful caller of `setValidator`
    uint public maxRewardPayout = 1 ether;
    // The bridge pallet (pseudo) address this contract is paired with
    address public palletAddress =
        address(0x6D6f646C65746879627264670000000000000000);
    // Max message length allowed
    uint public maxMessageLength = 1024; // 1kb
    // Fee required to be paid for SendMessage calls
    uint256 internal _sendMessageFee = 3e14; // 0.0003 ether
    // Message fees accumulated by the bridge
    uint public accumulatedMessageFees;

    event MessageReceived(
        uint indexed eventId,
        address indexed source,
        address indexed destinate,
        bytes message
    );
    event SetValidators(
        bytes32 indexed validatorSetDigest,
        uint256 indexed reward,
        uint32 indexed validatorSetId
    );
    event ForceSetActiveValidators(
        bytes32 indexed validatorSetDigest,
        uint32 indexed validatorSetId
    );
    event ForceSetHistoricValidators(
        bytes32 indexed validatorSetDigest,
        uint32 indexed validatorSetId
    );
    event BridgeFeeUpdated(uint indexed bridgeFee);
    event ThresholdUpdated(uint indexed thresholdPercent);
    event ProofTTLUpdated(uint indexed proofTTL);
    event BridgeActiveUpdated(bool indexed active);
    event MaxRewardPayoutUpdated(uint indexed maxRewardPayout);
    event PalletAddressUpdated(address indexed palletAddress);
    event MaxMessageLengthUpdated(uint indexed maxMessageLength);
    event SentEventIdUpdated(uint indexed _newId);
    event Endowed(uint256 indexed amount);
    event EtherWithdrawn(address _to, uint256 _amount);
    event WithdrawnMessageFees(address indexed recipient, uint indexed amount);
    event SendMessageFeeUpdated(uint256 indexed sendMessageFee);

    /// @notice Emit an event for the remote chain
    function sendMessage(address destination, bytes calldata message)
        external
        payable
        override
    {
        require(active, "Bridge: bridge inactive");
        require(message.length <= maxMessageLength, "Bridge: msg exceeds max length");
        require(msg.value >= _sendMessageFee, "Bridge: insufficient message fee");
        accumulatedMessageFees += msg.value;
        emit SendMessage(sentEventId++, msg.sender, destination, message, msg.value);
    }

    function sendMessageFee() external override view returns (uint256) {
        return _sendMessageFee;
    }

    /// @notice Receive a message from the remote chain
    /// @param proof contains a list of validator signature data and respective addresses - retrieved via RPC call from the remote chain
    function receiveMessage(
        address source,
        address destination,
        bytes calldata appMessage,
        EventProof calldata proof
    ) external payable override {
        require(
            msg.value >= bridgeFee || destination == address(this),
            "Bridge: must supply bridge fee"
        );
        require(appMessage.length > 0, "Bridge: empty message");

        bytes memory preimage = abi.encode(
            source,
            destination,
            appMessage,
            proof.validatorSetId,
            proof.eventId
        );
        _verifyMessage(preimage, proof);

        emit MessageReceived(proof.eventId, source, destination, appMessage);

        // call bridge receiver
        IBridgeReceiver(destination).onMessageReceived(source, appMessage);
    }

    /// @notice Verify a message was authorised by validators.
    /// - Callable by anyone.
    /// - Caller must provide `bridgeFee`.
    /// - Requires signatures from a threshold validators at proof.validatorSetId.
    /// - Requires proof is not older than `proofTTL` eras
    /// - Halts on failure
    ///
    /// @dev Parameters:
    /// - preimage: the unhashed message data packed wide w source, dest, validatorSetId & eventId e.g. `abi.encode(source, dest, message, validatorSetId, eventId);`
    /// - proof: Signed witness material generated by proving 'message'
    ///     - v,r,s are sparse arrays expected to align w public key in 'validators'
    ///     - i.e. v[i], r[i], s[i] matches the i-th validator[i]
    function _verifyMessage(bytes memory preimage, EventProof calldata proof)
        internal
    {
        // gas savings
        uint256 _eventId = proof.eventId;
        uint32 _validatorSetId = proof.validatorSetId;
        address[] memory _validators = proof.validators;

        require(active, "Bridge: bridge inactive");
        require(!verifiedEventIds[_eventId], "Bridge: eventId replayed");
        require(
            _validatorSetId <= activeValidatorSetId,
            "Bridge: future validator set"
        );
        require(
            activeValidatorSetId - _validatorSetId <= proofTTL,
            "Bridge: expired proof"
        );
        // audit item #1
        require(_validators.length > 0, "Bridge: invalid validator set");
        require(
            keccak256(abi.encode(_validators)) ==
                validatorSetDigests[_validatorSetId],
            "Bridge: unexpected validator digest"
        );

        bytes32 digest = keccak256(preimage);
        uint acceptanceTreshold = ((_validators.length * thresholdPercent) /
            100);
        uint witnessCount; // uint256(0)
        bytes32 ommited; // bytes32(0)

        for (uint i; i < _validators.length; ++i) {
            if (proof.r[i] != ommited) { // check signature omitted == bytes32(0)
                // check signature
                require(
                    _validators[i] == digest.recover(proof.v[i], proof.r[i], proof.s[i]),
                    "Bridge: signature invalid"
                );
                witnessCount += 1;
                // have we got proven consensus?
                if (witnessCount >= acceptanceTreshold) {
                    break;
                }
            }
        }

        require(witnessCount >= acceptanceTreshold, "Bridge: not enough signatures");
        verifiedEventIds[_eventId] = true;
    }

    /// @notice Handle a verified message provided by 'receiveMessage` to update the next validator set
    /// i.e. The bridge contract is itself a bridge app contract
    function onMessageReceived(address source, bytes calldata message)
        external
        override
    {
        require(msg.sender == address(this), "Bridge: only bridge can call");
        require(source == palletAddress, "Bridge: source must be pallet");
        (address[] memory newValidators, uint32 newValidatorSetId) = abi.decode(
            message,
            (address[], uint32)
        );
        _setValidators(newValidators, newValidatorSetId);
    }

    /// @dev Update the known validator set (must be called via 'relayMessage' with a valid proof of new validator set)
    function _setValidators(
        address[] memory newValidators,
        uint32 newValidatorSetId
    ) internal nonReentrant {
        require(newValidators.length > 0, "Bridge: empty validator set"); // also checked in _verifyMessage
        require(
            newValidatorSetId > activeValidatorSetId,
            "Bridge: validator set id replayed"
        );

        // update set digest and active id
        bytes32 validatorSetDigest = keccak256(abi.encode(newValidators));
        validatorSetDigests[newValidatorSetId] = validatorSetDigest;
        activeValidatorSetId = newValidatorSetId;

        // return accumulated fees to the sender as a reward, capped at `maxRewardPayout`
        uint reward = Math.min(address(this).balance - accumulatedMessageFees, maxRewardPayout);
        (bool sent, ) = tx.origin.call{value: reward}("");
        require(sent, "Bridge: Failed to send reward");

        emit SetValidators(validatorSetDigest, reward, newValidatorSetId);
    }

    /// @dev See {IERC165-supportsInterface}. Docs: https://docs.openzeppelin.com/contracts/4.x/api/utils#IERC165
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return
            interfaceId == type(IBridge).interfaceId ||
            interfaceId == type(IBridgeReceiver).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    // ============================================================================================================= //
    // ============================================== Admin functions ============================================== //
    // ============================================================================================================= //

    /// @notice force set the active validator set
    /// @dev newValidatorSetId can be equal to current activeValidatorSetId - to override current validators
    function forceActiveValidatorSet(
        address[] calldata newValidators,
        uint32 newValidatorSetId
    ) external onlyOwner {
        require(newValidators.length > 0, "Bridge: empty validator set");
        require(newValidatorSetId >= activeValidatorSetId, "Bridge: set is historic");
        bytes32 validatorSetDigest = keccak256(abi.encode(newValidators));
        validatorSetDigests[newValidatorSetId] = validatorSetDigest;
        activeValidatorSetId = newValidatorSetId;
        emit ForceSetActiveValidators(validatorSetDigest, newValidatorSetId);
    }

    /// @notice Force set a historic validator set
    /// @dev Sets older than proofTTL are not modifiable (since they cannot produce valid proofs any longer)
    function forceHistoricValidatorSet(
        address[] calldata _validators,
        uint32 validatorSetId
    ) external onlyOwner {
        require(_validators.length > 0, "Bridge: empty validator set");
        require(
            validatorSetId + proofTTL > activeValidatorSetId,
            "Bridge: set is inactive"
        );
        bytes32 validatorSetDigest = keccak256(abi.encode(_validators));
        validatorSetDigests[validatorSetId] = validatorSetDigest;
        emit ForceSetHistoricValidators(validatorSetDigest, validatorSetId);
    }

    /// @notice Set the TTL for historic validator set proofs
    function setProofTTL(uint256 _proofTTL) external onlyOwner {
        proofTTL = _proofTTL;
        emit ProofTTLUpdated(_proofTTL);
    }

    /// @notice Set the max reward payout for `setValidator` incentive
    function setMaxRewardPayout(uint256 _maxRewardPayout) external onlyOwner {
        maxRewardPayout = _maxRewardPayout;
        emit MaxRewardPayoutUpdated(_maxRewardPayout);
    }

    /// @notice Set the sentEventId for the contract to start with
    function setSentEventId(uint _newId) external onlyOwner {
        sentEventId = _newId;
        emit SentEventIdUpdated(_newId);
    }

    /// @notice Set the fee for verify messages
    function setBridgeFee(uint256 _bridgeFee) external onlyOwner {
        bridgeFee = _bridgeFee;
        emit BridgeFeeUpdated(_bridgeFee);
    }

    /// @notice Set the threshold % required for proof verification
    function setThreshold(uint256 _thresholdPercent) external onlyOwner {
        require(_thresholdPercent <= 100, "Bridge: percent must be <= 100");
        thresholdPercent = _thresholdPercent;
        emit ThresholdUpdated(_thresholdPercent);
    }

    /// @notice Set the pallet address
    function setPalletAddress(address _palletAddress) external onlyOwner {
        palletAddress = _palletAddress;
        emit PalletAddressUpdated(_palletAddress);
    }

    /// @notice Activate/deactivate the bridge
    function setActive(bool _active) external onlyOwner {
        active = _active;
        emit BridgeActiveUpdated(_active);
    }

    /// @dev Reset max message length
    function setMaxMessageLength(uint256 _maxMessageLength) external onlyOwner {
        maxMessageLength = _maxMessageLength;
        emit MaxMessageLengthUpdated(_maxMessageLength);
    }

    /// @dev Endow the contract with ether
    function endow() external payable {
        require(msg.value > 0, "Bridge: must endow nonzero");
        emit Endowed(msg.value);
    }

    /// @dev Owner can withdraw ether from the contract (primarily to support contract upgradability)
    function withdrawAll(address payable _to) public onlyOwner {
        uint256 balance = address(this).balance;
        (bool sent,) = _to.call{value: balance}("");
        require(sent, "Bridge: failed to send Ether");
        emit EtherWithdrawn(_to, balance);
    }

    /// @dev Set _sendMessageFee
    function setSendMessageFee(uint256 _fee) external onlyOwner {
        _sendMessageFee = _fee;
        emit SendMessageFeeUpdated(_fee);
    }

    /// @dev Owner can withdraw accumulates msg fees from the contract
    function withdrawMsgFees(address payable _to, uint256 _amount) public onlyOwner {
        accumulatedMessageFees -= _amount; // prevent re-entrancy protection
        (bool sent, ) = _to.call{value: _amount}("");
        require(sent, "Bridge: Failed to send msg fees");
        emit WithdrawnMessageFees(_to, _amount);
    }
}

File 2 of 10 : IBridge.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.17;

// Proof of a witnessed event by validators
struct EventProof {
    // The Id (nonce) of the event
    uint256 eventId;
    // The validator set Id which witnessed the event
    uint32 validatorSetId;
    // v,r,s are sparse arrays expected to align w public key in 'validators'
    // i.e. v[i], r[i], s[i] matches the i-th validator[i]
    // v part of validator signatures
    uint8[] v;
    // r part of validator signatures
    bytes32[] r;
    // s part of validator signatures
    bytes32[] s;
    // The validator addresses
    address[] validators;
}

interface IBridge {
    // A sent message event
    event SendMessage(uint messageId, address source, address destination, bytes message, uint256 fee);
    // Receive a bridge message from the remote chain
    function receiveMessage(address source, address destination, bytes calldata message, EventProof calldata proof) external payable;
    // Send a bridge message to the remote chain
    function sendMessage(address destination, bytes calldata message) external payable;
    // Send message fee - used by sendMessage caller to obtain required fee for sendMessage
    function sendMessageFee() external view returns (uint256);
}

interface IBridgeReceiver {
    // Handle a bridge message received from the remote chain
    // It is guaranteed to be valid
    function onMessageReceived(address source, bytes calldata message) external;
}

File 3 of 10 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 4 of 10 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 5 of 10 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 6 of 10 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 7 of 10 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`.
        // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.
        // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.
        // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a
        // good first aproximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1;
        uint256 x = a;
        if (x >> 128 > 0) {
            x >>= 128;
            result <<= 64;
        }
        if (x >> 64 > 0) {
            x >>= 64;
            result <<= 32;
        }
        if (x >> 32 > 0) {
            x >>= 32;
            result <<= 16;
        }
        if (x >> 16 > 0) {
            x >>= 16;
            result <<= 8;
        }
        if (x >> 8 > 0) {
            x >>= 8;
            result <<= 4;
        }
        if (x >> 4 > 0) {
            x >>= 4;
            result <<= 2;
        }
        if (x >> 2 > 0) {
            result <<= 1;
        }

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        uint256 result = sqrt(a);
        if (rounding == Rounding.Up && result * result < a) {
            result += 1;
        }
        return result;
    }
}

File 8 of 10 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 9 of 10 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

File 10 of 10 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"active","type":"bool"}],"name":"BridgeActiveUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"bridgeFee","type":"uint256"}],"name":"BridgeFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Endowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"EtherWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"validatorSetDigest","type":"bytes32"},{"indexed":true,"internalType":"uint32","name":"validatorSetId","type":"uint32"}],"name":"ForceSetActiveValidators","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"validatorSetDigest","type":"bytes32"},{"indexed":true,"internalType":"uint32","name":"validatorSetId","type":"uint32"}],"name":"ForceSetHistoricValidators","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"maxMessageLength","type":"uint256"}],"name":"MaxMessageLengthUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"maxRewardPayout","type":"uint256"}],"name":"MaxRewardPayoutUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"eventId","type":"uint256"},{"indexed":true,"internalType":"address","name":"source","type":"address"},{"indexed":true,"internalType":"address","name":"destinate","type":"address"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"MessageReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"palletAddress","type":"address"}],"name":"PalletAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proofTTL","type":"uint256"}],"name":"ProofTTLUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"messageId","type":"uint256"},{"indexed":false,"internalType":"address","name":"source","type":"address"},{"indexed":false,"internalType":"address","name":"destination","type":"address"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SendMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sendMessageFee","type":"uint256"}],"name":"SendMessageFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_newId","type":"uint256"}],"name":"SentEventIdUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"validatorSetDigest","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":true,"internalType":"uint32","name":"validatorSetId","type":"uint32"}],"name":"SetValidators","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"thresholdPercent","type":"uint256"}],"name":"ThresholdUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawnMessageFees","type":"event"},{"inputs":[],"name":"accumulatedMessageFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"active","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activeValidatorSetId","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridgeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endow","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"newValidators","type":"address[]"},{"internalType":"uint32","name":"newValidatorSetId","type":"uint32"}],"name":"forceActiveValidatorSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_validators","type":"address[]"},{"internalType":"uint32","name":"validatorSetId","type":"uint32"}],"name":"forceHistoricValidatorSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxMessageLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxRewardPayout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"source","type":"address"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"onMessageReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"palletAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proofTTL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"source","type":"address"},{"internalType":"address","name":"destination","type":"address"},{"internalType":"bytes","name":"appMessage","type":"bytes"},{"components":[{"internalType":"uint256","name":"eventId","type":"uint256"},{"internalType":"uint32","name":"validatorSetId","type":"uint32"},{"internalType":"uint8[]","name":"v","type":"uint8[]"},{"internalType":"bytes32[]","name":"r","type":"bytes32[]"},{"internalType":"bytes32[]","name":"s","type":"bytes32[]"},{"internalType":"address[]","name":"validators","type":"address[]"}],"internalType":"struct EventProof","name":"proof","type":"tuple"}],"name":"receiveMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"destination","type":"address"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"sendMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sendMessageFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sentEventId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_active","type":"bool"}],"name":"setActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bridgeFee","type":"uint256"}],"name":"setBridgeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxMessageLength","type":"uint256"}],"name":"setMaxMessageLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxRewardPayout","type":"uint256"}],"name":"setMaxRewardPayout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_palletAddress","type":"address"}],"name":"setPalletAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proofTTL","type":"uint256"}],"name":"setProofTTL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setSendMessageFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newId","type":"uint256"}],"name":"setSentEventId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_thresholdPercent","type":"uint256"}],"name":"setThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"thresholdPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"validatorSetDigests","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"verifiedEventIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"}],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawMsgFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052660e35fa931a0000600655603c60075560076008556000600960006101000a81548160ff021916908315150217905550670de0b6b3a7640000600a55736d6f646c65746879627264670000000000000000600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610400600c55660110d9316ec000600d55348015620000b357600080fd5b50620000d4620000c8620000e160201b60201c565b620000e960201b60201c565b60018081905550620001ad565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613f8080620001bd6000396000f3fe6080604052600436106101f95760003560e01c80637755618b1161010d5780639c11bc30116100a0578063cfc16cea1161006f578063cfc16cea14610696578063d87500db146106c1578063f0bdb2d1146106fe578063f2fde38b14610727578063fa09e63014610750576101f9565b80639c11bc30146105fd578063acec338a14610626578063bb5ddb0f1461064f578063c6c0f59e1461066b576101f9565b80638da5cb5b116100dc5780638da5cb5b14610543578063960bfe041461056e578063996b2f9414610597578063998cdf83146105d4576101f9565b80637755618b146104a8578063823d2fc8146104d157806382b12dd7146104ed57806387b50acb14610518576101f9565b80634008b03f1161019057806361ab5a781161015f57806361ab5a78146103eb578063650bd364146104145780636a70fef21461043d578063715018a614610468578063728952f81461047f576101f9565b80634008b03f146103435780634acf77211461036c57806350dcb027146103955780635f7e9399146103c0576101f9565b80632c05f9a2116101cc5780632c05f9a21461029b5780632ee111ed146102c65780633301a464146102ef5780633ab578aa14610318576101f9565b806301ffc9a7146101fe57806302fb0c5e1461023b57806306e30dfc146102665780631d1d4e2914610270575b600080fd5b34801561020a57600080fd5b50610225600480360381019061022091906122b4565b610779565b60405161023291906122fc565b60405180910390f35b34801561024757600080fd5b5061025061085b565b60405161025d91906122fc565b60405180910390f35b61026e61086e565b005b34801561027c57600080fd5b506102856108e0565b6040516102929190612330565b60405180910390f35b3480156102a757600080fd5b506102b06108e6565b6040516102bd9190612330565b60405180910390f35b3480156102d257600080fd5b506102ed60048036038101906102e891906123a9565b6108ec565b005b3480156102fb57600080fd5b5061031660048036038101906103119190612402565b61097b565b005b34801561032457600080fd5b5061032d6109ba565b60405161033a9190612330565b60405180910390f35b34801561034f57600080fd5b5061036a600480360381019061036591906124d0565b6109c0565b005b34801561037857600080fd5b50610393600480360381019061038e91906124d0565b610b00565b005b3480156103a157600080fd5b506103aa610c55565b6040516103b79190612330565b60405180910390f35b3480156103cc57600080fd5b506103d5610c5f565b6040516103e2919061253f565b60405180910390f35b3480156103f757600080fd5b50610412600480360381019061040d9190612402565b610c75565b005b34801561042057600080fd5b5061043b600480360381019061043691906125b0565b610cb4565b005b34801561044957600080fd5b50610452610dd9565b60405161045f9190612330565b60405180910390f35b34801561047457600080fd5b5061047d610ddf565b005b34801561048b57600080fd5b506104a660048036038101906104a19190612402565b610df3565b005b3480156104b457600080fd5b506104cf60048036038101906104ca9190612402565b610e32565b005b6104eb60048036038101906104e69190612634565b610e71565b005b3480156104f957600080fd5b50610502611063565b60405161050f9190612330565b60405180910390f35b34801561052457600080fd5b5061052d611069565b60405161053a9190612330565b60405180910390f35b34801561054f57600080fd5b5061055861106f565b60405161056591906126e7565b60405180910390f35b34801561057a57600080fd5b5061059560048036038101906105909190612402565b611098565b005b3480156105a357600080fd5b506105be60048036038101906105b99190612402565b61111b565b6040516105cb919061271b565b60405180910390f35b3480156105e057600080fd5b506105fb60048036038101906105f69190612402565b611133565b005b34801561060957600080fd5b50610624600480360381019061061f9190612402565b611172565b005b34801561063257600080fd5b5061064d60048036038101906106489190612762565b6111b1565b005b610669600480360381019061066491906125b0565b611205565b005b34801561067757600080fd5b50610680611356565b60405161068d91906126e7565b60405180910390f35b3480156106a257600080fd5b506106ab61137c565b6040516106b89190612330565b60405180910390f35b3480156106cd57600080fd5b506106e860048036038101906106e39190612402565b611382565b6040516106f591906122fc565b60405180910390f35b34801561070a57600080fd5b50610725600480360381019061072091906127cd565b6113a2565b005b34801561073357600080fd5b5061074e600480360381019061074991906123a9565b6114b8565b005b34801561075c57600080fd5b506107776004803603810190610772919061280d565b61153b565b005b60007f69bc44e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061084457507f650bd364000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610854575061085382611632565b5b9050919050565b600960009054906101000a900460ff1681565b600034116108b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a890612897565b60405180910390fd5b347f840be946bba3df0d184eb7e6cd7c9e57bb380cf6078516c7441db5709d58509860405160405180910390a2565b600c5481565b600a5481565b6108f461169c565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f679cb5acfebd038830b61daadd5f2f74e2114862b1c289a5d2db82bc6eda32a660405160405180910390a250565b61098361169c565b80600a81905550807f11cff79cc5c082b5f775ae922a2a6dc80e9f79b9207767278bdf7391db5467f760405160405180910390a250565b60085481565b6109c861169c565b60008383905011610a0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0590612903565b60405180910390fd5b600360009054906101000a900463ffffffff1663ffffffff166008548263ffffffff16610a3b9190612952565b11610a7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a72906129d2565b60405180910390fd5b60008383604051602001610a90929190612ab5565b60405160208183030381529060405280519060200120905080600260008463ffffffff168152602001908152602001600020819055508163ffffffff16817ff541dede932a20dba17286430555d7aa784b74222f2a34f107d40822f41992e360405160405180910390a350505050565b610b0861169c565b60008383905011610b4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4590612903565b60405180910390fd5b600360009054906101000a900463ffffffff1663ffffffff168163ffffffff161015610baf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba690612b25565b60405180910390fd5b60008383604051602001610bc4929190612ab5565b60405160208183030381529060405280519060200120905080600260008463ffffffff1681526020019081526020016000208190555081600360006101000a81548163ffffffff021916908363ffffffff1602179055508163ffffffff16817f36885d9a49d239da5379a6f8f9bb89273332a7e312cb5b8a2d3b0f567e8209f460405160405180910390a350505050565b6000600d54905090565b600360009054906101000a900463ffffffff1681565b610c7d61169c565b80600481905550807f06055c66c43187163b022b7d954ff32b4ba5265e175458d1b134cfe8ab72f41260405160405180910390a250565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1990612b91565b60405180910390fd5b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990612bfd565b60405180910390fd5b6000808383810190610dc49190612d6c565b91509150610dd2828261171a565b5050505050565b600e5481565b610de761169c565b610df16000611981565b565b610dfb61169c565b80600d81905550807fabd57ef278738881488128581f298faa35ba1bae2bbec9fb6e370ff60d531e4b60405160405180910390a250565b610e3a61169c565b80600881905550807f01116a77fa86522c55d40463f1b48825870a5d04ea15ca52a166d8ace7f355ff60405160405180910390a250565b60065434101580610ead57503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b610eec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee390612e14565b60405180910390fd5b60008383905011610f32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2990612e80565b60405180910390fd5b600085858585856020016020810190610f4b9190612ea0565b8660000135604051602001610f6596959493929190612f1a565b6040516020818303038152906040529050610f808183611a45565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1683600001357f3591658888eebc109961f7116a3e6aafbbeb08b55e727cf69c44d466a77a90d18787604051610fe4929190612f76565b60405180910390a48473ffffffffffffffffffffffffffffffffffffffff1663650bd3648786866040518463ffffffff1660e01b815260040161102993929190612f9a565b600060405180830381600087803b15801561104357600080fd5b505af1158015611057573d6000803e3d6000fd5b50505050505050505050565b60065481565b60045481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6110a061169c565b60648111156110e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110db90613018565b60405180910390fd5b80600781905550807fadfa8ecb21b6962ebcd0adbd9ab985b7b4c5b5eb3b0dead683171565c7bfe17160405160405180910390a250565b60026020528060005260406000206000915090505481565b61113b61169c565b80600681905550807f42dfb00d085d601e55327921154ae76c1b24270b026c5a0c51caee18eb4c401f60405160405180910390a250565b61117a61169c565b80600c81905550807f80e9dc023eeed9cbe4e886f225681c4fa94a046011c6269619c21befd6c4518160405160405180910390a250565b6111b961169c565b80600960006101000a81548160ff0219169083151502179055508015157fd06b0db8a7172c6c142c15cd90b6efb883b600b978dfca380621aa4c9f6d881560405160405180910390a250565b600960009054906101000a900460ff16611254576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124b90613084565b60405180910390fd5b600c5482829050111561129c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611293906130f0565b60405180910390fd5b600d543410156112e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d89061315c565b60405180910390fd5b34600e60008282546112f39190612952565b925050819055507ff2a50cd57a795ad452a0b8586bcd3fe8e3ee00054c01c4712655d7753539dd356004600081548092919061132e9061317c565b919050553385858534604051611349969594939291906131c4565b60405180910390a1505050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60075481565b60056020528060005260406000206000915054906101000a900460ff1681565b6113aa61169c565b80600e60008282546113bc9190613220565b9250508190555060008273ffffffffffffffffffffffffffffffffffffffff16826040516113e990613285565b60006040518083038185875af1925050503d8060008114611426576040519150601f19603f3d011682016040523d82523d6000602084013e61142b565b606091505b505090508061146f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611466906132e6565b60405180910390fd5b818373ffffffffffffffffffffffffffffffffffffffff167fcc89aff20f6022ea39ee28e42ebe0013f5e8a32d9388b49d2f6fe08563a54cdf60405160405180910390a3505050565b6114c061169c565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161152690613378565b60405180910390fd5b61153881611981565b50565b61154361169c565b600047905060008273ffffffffffffffffffffffffffffffffffffffff168260405161156e90613285565b60006040518083038185875af1925050503d80600081146115ab576040519150601f19603f3d011682016040523d82523d6000602084013e6115b0565b606091505b50509050806115f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115eb906133e4565b60405180910390fd5b7f06097061aeda806b5e9cb4133d9899f332ff0913956567fc0f7ea15e3d19947c8383604051611625929190613463565b60405180910390a1505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6116a4611f24565b73ffffffffffffffffffffffffffffffffffffffff166116c261106f565b73ffffffffffffffffffffffffffffffffffffffff1614611718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170f906134d8565b60405180910390fd5b565b60026001540361175f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175690613544565b60405180910390fd5b600260018190555060008251116117ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a290612903565b60405180910390fd5b600360009054906101000a900463ffffffff1663ffffffff168163ffffffff161161180b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611802906135d6565b60405180910390fd5b60008260405160200161181e919061367c565b60405160208183030381529060405280519060200120905080600260008463ffffffff1681526020019081526020016000208190555081600360006101000a81548163ffffffff021916908363ffffffff1602179055506000611890600e54476118889190613220565b600a54611f2c565b905060003273ffffffffffffffffffffffffffffffffffffffff16826040516118b890613285565b60006040518083038185875af1925050503d80600081146118f5576040519150601f19603f3d011682016040523d82523d6000602084013e6118fa565b606091505b505090508061193e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611935906136ea565b60405180910390fd5b8363ffffffff1682847f3dab4e75c61b76a4152c289f3c93392ddab6386b2423ffab2cee4da9fbb05c7160405160405180910390a4505050600180819055505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000816000013590506000826020016020810190611a639190612ea0565b90506000838060a00190611a779190613719565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509050600960009054906101000a900460ff16611b08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aff90613084565b60405180910390fd5b6005600084815260200190815260200160002060009054906101000a900460ff1615611b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b60906137c8565b60405180910390fd5b600360009054906101000a900463ffffffff1663ffffffff168263ffffffff161115611bca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc190613834565b60405180910390fd5b60085482600360009054906101000a900463ffffffff16611beb9190613854565b63ffffffff161115611c32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c29906138d8565b60405180910390fd5b6000815111611c76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c6d90613944565b60405180910390fd5b600260008363ffffffff1681526020019081526020016000205481604051602001611ca1919061367c565b6040516020818303038152906040528051906020012014611cf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cee906139d6565b60405180910390fd5b600085805190602001209050600060646007548451611d1691906139f6565b611d209190613a67565b905060008060005b8551811015611ea95781898060600190611d429190613a98565b83818110611d5357611d52613afb565b5b9050602002013514611e9857611df9898060400190611d729190613b2a565b83818110611d8357611d82613afb565b5b9050602002016020810190611d989190613bc6565b8a8060600190611da89190613a98565b84818110611db957611db8613afb565b5b905060200201358b8060800190611dd09190613a98565b85818110611de157611de0613afb565b5b9050602002013588611f45909392919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16868281518110611e2257611e21613afb565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614611e80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7790613c3f565b60405180910390fd5b600183611e8d9190612952565b925083831015611ea9575b80611ea29061317c565b9050611d28565b5082821015611eed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee490613cab565b60405180910390fd5b60016005600089815260200190815260200160002060006101000a81548160ff021916908315150217905550505050505050505050565b600033905090565b6000818310611f3b5781611f3d565b825b905092915050565b6000806000611f5687878787611f70565b91509150611f638161207c565b8192505050949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115611fab576000600391509150612073565b601b8560ff1614158015611fc35750601c8560ff1614155b15611fd5576000600491509150612073565b600060018787878760405160008152602001604052604051611ffa9493929190613cda565b6020604051602081039080840390855afa15801561201c573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361206a57600060019250925050612073565b80600092509250505b94509492505050565b600060048111156120905761208f613d1f565b5b8160048111156120a3576120a2613d1f565b5b031561224557600160048111156120bd576120bc613d1f565b5b8160048111156120d0576120cf613d1f565b5b03612110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161210790613d9a565b60405180910390fd5b6002600481111561212457612123613d1f565b5b81600481111561213757612136613d1f565b5b03612177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161216e90613e06565b60405180910390fd5b6003600481111561218b5761218a613d1f565b5b81600481111561219e5761219d613d1f565b5b036121de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121d590613e98565b60405180910390fd5b6004808111156121f1576121f0613d1f565b5b81600481111561220457612203613d1f565b5b03612244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223b90613f2a565b60405180910390fd5b5b50565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6122918161225c565b811461229c57600080fd5b50565b6000813590506122ae81612288565b92915050565b6000602082840312156122ca576122c9612252565b5b60006122d88482850161229f565b91505092915050565b60008115159050919050565b6122f6816122e1565b82525050565b600060208201905061231160008301846122ed565b92915050565b6000819050919050565b61232a81612317565b82525050565b60006020820190506123456000830184612321565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006123768261234b565b9050919050565b6123868161236b565b811461239157600080fd5b50565b6000813590506123a38161237d565b92915050565b6000602082840312156123bf576123be612252565b5b60006123cd84828501612394565b91505092915050565b6123df81612317565b81146123ea57600080fd5b50565b6000813590506123fc816123d6565b92915050565b60006020828403121561241857612417612252565b5b6000612426848285016123ed565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126124545761245361242f565b5b8235905067ffffffffffffffff81111561247157612470612434565b5b60208301915083602082028301111561248d5761248c612439565b5b9250929050565b600063ffffffff82169050919050565b6124ad81612494565b81146124b857600080fd5b50565b6000813590506124ca816124a4565b92915050565b6000806000604084860312156124e9576124e8612252565b5b600084013567ffffffffffffffff81111561250757612506612257565b5b6125138682870161243e565b93509350506020612526868287016124bb565b9150509250925092565b61253981612494565b82525050565b60006020820190506125546000830184612530565b92915050565b60008083601f8401126125705761256f61242f565b5b8235905067ffffffffffffffff81111561258d5761258c612434565b5b6020830191508360018202830111156125a9576125a8612439565b5b9250929050565b6000806000604084860312156125c9576125c8612252565b5b60006125d786828701612394565b935050602084013567ffffffffffffffff8111156125f8576125f7612257565b5b6126048682870161255a565b92509250509250925092565b600080fd5b600060c0828403121561262b5761262a612610565b5b81905092915050565b6000806000806000608086880312156126505761264f612252565b5b600061265e88828901612394565b955050602061266f88828901612394565b945050604086013567ffffffffffffffff8111156126905761268f612257565b5b61269c8882890161255a565b9350935050606086013567ffffffffffffffff8111156126bf576126be612257565b5b6126cb88828901612615565b9150509295509295909350565b6126e18161236b565b82525050565b60006020820190506126fc60008301846126d8565b92915050565b6000819050919050565b61271581612702565b82525050565b6000602082019050612730600083018461270c565b92915050565b61273f816122e1565b811461274a57600080fd5b50565b60008135905061275c81612736565b92915050565b60006020828403121561277857612777612252565b5b60006127868482850161274d565b91505092915050565b600061279a8261234b565b9050919050565b6127aa8161278f565b81146127b557600080fd5b50565b6000813590506127c7816127a1565b92915050565b600080604083850312156127e4576127e3612252565b5b60006127f2858286016127b8565b9250506020612803858286016123ed565b9150509250929050565b60006020828403121561282357612822612252565b5b6000612831848285016127b8565b91505092915050565b600082825260208201905092915050565b7f4272696467653a206d75737420656e646f77206e6f6e7a65726f000000000000600082015250565b6000612881601a8361283a565b915061288c8261284b565b602082019050919050565b600060208201905081810360008301526128b081612874565b9050919050565b7f4272696467653a20656d7074792076616c696461746f72207365740000000000600082015250565b60006128ed601b8361283a565b91506128f8826128b7565b602082019050919050565b6000602082019050818103600083015261291c816128e0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061295d82612317565b915061296883612317565b92508282019050808211156129805761297f612923565b5b92915050565b7f4272696467653a2073657420697320696e616374697665000000000000000000600082015250565b60006129bc60178361283a565b91506129c782612986565b602082019050919050565b600060208201905081810360008301526129eb816129af565b9050919050565b600082825260208201905092915050565b6000819050919050565b612a168161236b565b82525050565b6000612a288383612a0d565b60208301905092915050565b6000612a436020840184612394565b905092915050565b6000602082019050919050565b6000612a6483856129f2565b9350612a6f82612a03565b8060005b85811015612aa857612a858284612a34565b612a8f8882612a1c565b9750612a9a83612a4b565b925050600181019050612a73565b5085925050509392505050565b60006020820190508181036000830152612ad0818486612a58565b90509392505050565b7f4272696467653a2073657420697320686973746f726963000000000000000000600082015250565b6000612b0f60178361283a565b9150612b1a82612ad9565b602082019050919050565b60006020820190508181036000830152612b3e81612b02565b9050919050565b7f4272696467653a206f6e6c79206272696467652063616e2063616c6c00000000600082015250565b6000612b7b601c8361283a565b9150612b8682612b45565b602082019050919050565b60006020820190508181036000830152612baa81612b6e565b9050919050565b7f4272696467653a20736f75726365206d7573742062652070616c6c6574000000600082015250565b6000612be7601d8361283a565b9150612bf282612bb1565b602082019050919050565b60006020820190508181036000830152612c1681612bda565b9050919050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612c6682612c1d565b810181811067ffffffffffffffff82111715612c8557612c84612c2e565b5b80604052505050565b6000612c98612248565b9050612ca48282612c5d565b919050565b600067ffffffffffffffff821115612cc457612cc3612c2e565b5b602082029050602081019050919050565b6000612ce8612ce384612ca9565b612c8e565b90508083825260208201905060208402830185811115612d0b57612d0a612439565b5b835b81811015612d345780612d208882612394565b845260208401935050602081019050612d0d565b5050509392505050565b600082601f830112612d5357612d5261242f565b5b8135612d63848260208601612cd5565b91505092915050565b60008060408385031215612d8357612d82612252565b5b600083013567ffffffffffffffff811115612da157612da0612257565b5b612dad85828601612d3e565b9250506020612dbe858286016124bb565b9150509250929050565b7f4272696467653a206d75737420737570706c7920627269646765206665650000600082015250565b6000612dfe601e8361283a565b9150612e0982612dc8565b602082019050919050565b60006020820190508181036000830152612e2d81612df1565b9050919050565b7f4272696467653a20656d707479206d6573736167650000000000000000000000600082015250565b6000612e6a60158361283a565b9150612e7582612e34565b602082019050919050565b60006020820190508181036000830152612e9981612e5d565b9050919050565b600060208284031215612eb657612eb5612252565b5b6000612ec4848285016124bb565b91505092915050565b600082825260208201905092915050565b82818337600083830152505050565b6000612ef98385612ecd565b9350612f06838584612ede565b612f0f83612c1d565b840190509392505050565b600060a082019050612f2f60008301896126d8565b612f3c60208301886126d8565b8181036040830152612f4f818688612eed565b9050612f5e6060830185612530565b612f6b6080830184612321565b979650505050505050565b60006020820190508181036000830152612f91818486612eed565b90509392505050565b6000604082019050612faf60008301866126d8565b8181036020830152612fc2818486612eed565b9050949350505050565b7f4272696467653a2070657263656e74206d757374206265203c3d203130300000600082015250565b6000613002601e8361283a565b915061300d82612fcc565b602082019050919050565b6000602082019050818103600083015261303181612ff5565b9050919050565b7f4272696467653a2062726964676520696e616374697665000000000000000000600082015250565b600061306e60178361283a565b915061307982613038565b602082019050919050565b6000602082019050818103600083015261309d81613061565b9050919050565b7f4272696467653a206d73672065786365656473206d6178206c656e6774680000600082015250565b60006130da601e8361283a565b91506130e5826130a4565b602082019050919050565b60006020820190508181036000830152613109816130cd565b9050919050565b7f4272696467653a20696e73756666696369656e74206d65737361676520666565600082015250565b600061314660208361283a565b915061315182613110565b602082019050919050565b6000602082019050818103600083015261317581613139565b9050919050565b600061318782612317565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036131b9576131b8612923565b5b600182019050919050565b600060a0820190506131d96000830189612321565b6131e660208301886126d8565b6131f360408301876126d8565b8181036060830152613206818587612eed565b90506132156080830184612321565b979650505050505050565b600061322b82612317565b915061323683612317565b925082820390508181111561324e5761324d612923565b5b92915050565b600081905092915050565b50565b600061326f600083613254565b915061327a8261325f565b600082019050919050565b600061329082613262565b9150819050919050565b7f4272696467653a204661696c656420746f2073656e64206d7367206665657300600082015250565b60006132d0601f8361283a565b91506132db8261329a565b602082019050919050565b600060208201905081810360008301526132ff816132c3565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061336260268361283a565b915061336d82613306565b604082019050919050565b6000602082019050818103600083015261339181613355565b9050919050565b7f4272696467653a206661696c656420746f2073656e6420457468657200000000600082015250565b60006133ce601c8361283a565b91506133d982613398565b602082019050919050565b600060208201905081810360008301526133fd816133c1565b9050919050565b6000819050919050565b600061342961342461341f8461234b565b613404565b61234b565b9050919050565b600061343b8261340e565b9050919050565b600061344d82613430565b9050919050565b61345d81613442565b82525050565b60006040820190506134786000830185613454565b6134856020830184612321565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006134c260208361283a565b91506134cd8261348c565b602082019050919050565b600060208201905081810360008301526134f1816134b5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061352e601f8361283a565b9150613539826134f8565b602082019050919050565b6000602082019050818103600083015261355d81613521565b9050919050565b7f4272696467653a2076616c696461746f7220736574206964207265706c61796560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b60006135c060218361283a565b91506135cb82613564565b604082019050919050565b600060208201905081810360008301526135ef816135b3565b9050919050565b600081519050919050565b6000819050602082019050919050565b6000602082019050919050565b6000613629826135f6565b61363381856129f2565b935061363e83613601565b8060005b8381101561366f5781516136568882612a1c565b975061366183613611565b925050600181019050613642565b5085935050505092915050565b60006020820190508181036000830152613696818461361e565b905092915050565b7f4272696467653a204661696c656420746f2073656e6420726577617264000000600082015250565b60006136d4601d8361283a565b91506136df8261369e565b602082019050919050565b60006020820190508181036000830152613703816136c7565b9050919050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126137365761373561370a565b5b80840192508235915067ffffffffffffffff8211156137585761375761370f565b5b60208301925060208202360383131561377457613773613714565b5b509250929050565b7f4272696467653a206576656e744964207265706c617965640000000000000000600082015250565b60006137b260188361283a565b91506137bd8261377c565b602082019050919050565b600060208201905081810360008301526137e1816137a5565b9050919050565b7f4272696467653a206675747572652076616c696461746f722073657400000000600082015250565b600061381e601c8361283a565b9150613829826137e8565b602082019050919050565b6000602082019050818103600083015261384d81613811565b9050919050565b600061385f82612494565b915061386a83612494565b9250828203905063ffffffff81111561388657613885612923565b5b92915050565b7f4272696467653a20657870697265642070726f6f660000000000000000000000600082015250565b60006138c260158361283a565b91506138cd8261388c565b602082019050919050565b600060208201905081810360008301526138f1816138b5565b9050919050565b7f4272696467653a20696e76616c69642076616c696461746f7220736574000000600082015250565b600061392e601d8361283a565b9150613939826138f8565b602082019050919050565b6000602082019050818103600083015261395d81613921565b9050919050565b7f4272696467653a20756e65787065637465642076616c696461746f722064696760008201527f6573740000000000000000000000000000000000000000000000000000000000602082015250565b60006139c060238361283a565b91506139cb82613964565b604082019050919050565b600060208201905081810360008301526139ef816139b3565b9050919050565b6000613a0182612317565b9150613a0c83612317565b9250828202613a1a81612317565b91508282048414831517613a3157613a30612923565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613a7282612317565b9150613a7d83612317565b925082613a8d57613a8c613a38565b5b828204905092915050565b60008083356001602003843603038112613ab557613ab461370a565b5b80840192508235915067ffffffffffffffff821115613ad757613ad661370f565b5b602083019250602082023603831315613af357613af2613714565b5b509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083356001602003843603038112613b4757613b4661370a565b5b80840192508235915067ffffffffffffffff821115613b6957613b6861370f565b5b602083019250602082023603831315613b8557613b84613714565b5b509250929050565b600060ff82169050919050565b613ba381613b8d565b8114613bae57600080fd5b50565b600081359050613bc081613b9a565b92915050565b600060208284031215613bdc57613bdb612252565b5b6000613bea84828501613bb1565b91505092915050565b7f4272696467653a207369676e617475726520696e76616c696400000000000000600082015250565b6000613c2960198361283a565b9150613c3482613bf3565b602082019050919050565b60006020820190508181036000830152613c5881613c1c565b9050919050565b7f4272696467653a206e6f7420656e6f756768207369676e617475726573000000600082015250565b6000613c95601d8361283a565b9150613ca082613c5f565b602082019050919050565b60006020820190508181036000830152613cc481613c88565b9050919050565b613cd481613b8d565b82525050565b6000608082019050613cef600083018761270c565b613cfc6020830186613ccb565b613d09604083018561270c565b613d16606083018461270c565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000613d8460188361283a565b9150613d8f82613d4e565b602082019050919050565b60006020820190508181036000830152613db381613d77565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000613df0601f8361283a565b9150613dfb82613dba565b602082019050919050565b60006020820190508181036000830152613e1f81613de3565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000613e8260228361283a565b9150613e8d82613e26565b604082019050919050565b60006020820190508181036000830152613eb181613e75565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000613f1460228361283a565b9150613f1f82613eb8565b604082019050919050565b60006020820190508181036000830152613f4381613f07565b905091905056fea2646970667358221220f9a8d1b86a248b8c1da50bc478fabe85896722e6801967a7060316a27baa54eb64736f6c63430008110033

Deployed Bytecode

0x6080604052600436106101f95760003560e01c80637755618b1161010d5780639c11bc30116100a0578063cfc16cea1161006f578063cfc16cea14610696578063d87500db146106c1578063f0bdb2d1146106fe578063f2fde38b14610727578063fa09e63014610750576101f9565b80639c11bc30146105fd578063acec338a14610626578063bb5ddb0f1461064f578063c6c0f59e1461066b576101f9565b80638da5cb5b116100dc5780638da5cb5b14610543578063960bfe041461056e578063996b2f9414610597578063998cdf83146105d4576101f9565b80637755618b146104a8578063823d2fc8146104d157806382b12dd7146104ed57806387b50acb14610518576101f9565b80634008b03f1161019057806361ab5a781161015f57806361ab5a78146103eb578063650bd364146104145780636a70fef21461043d578063715018a614610468578063728952f81461047f576101f9565b80634008b03f146103435780634acf77211461036c57806350dcb027146103955780635f7e9399146103c0576101f9565b80632c05f9a2116101cc5780632c05f9a21461029b5780632ee111ed146102c65780633301a464146102ef5780633ab578aa14610318576101f9565b806301ffc9a7146101fe57806302fb0c5e1461023b57806306e30dfc146102665780631d1d4e2914610270575b600080fd5b34801561020a57600080fd5b50610225600480360381019061022091906122b4565b610779565b60405161023291906122fc565b60405180910390f35b34801561024757600080fd5b5061025061085b565b60405161025d91906122fc565b60405180910390f35b61026e61086e565b005b34801561027c57600080fd5b506102856108e0565b6040516102929190612330565b60405180910390f35b3480156102a757600080fd5b506102b06108e6565b6040516102bd9190612330565b60405180910390f35b3480156102d257600080fd5b506102ed60048036038101906102e891906123a9565b6108ec565b005b3480156102fb57600080fd5b5061031660048036038101906103119190612402565b61097b565b005b34801561032457600080fd5b5061032d6109ba565b60405161033a9190612330565b60405180910390f35b34801561034f57600080fd5b5061036a600480360381019061036591906124d0565b6109c0565b005b34801561037857600080fd5b50610393600480360381019061038e91906124d0565b610b00565b005b3480156103a157600080fd5b506103aa610c55565b6040516103b79190612330565b60405180910390f35b3480156103cc57600080fd5b506103d5610c5f565b6040516103e2919061253f565b60405180910390f35b3480156103f757600080fd5b50610412600480360381019061040d9190612402565b610c75565b005b34801561042057600080fd5b5061043b600480360381019061043691906125b0565b610cb4565b005b34801561044957600080fd5b50610452610dd9565b60405161045f9190612330565b60405180910390f35b34801561047457600080fd5b5061047d610ddf565b005b34801561048b57600080fd5b506104a660048036038101906104a19190612402565b610df3565b005b3480156104b457600080fd5b506104cf60048036038101906104ca9190612402565b610e32565b005b6104eb60048036038101906104e69190612634565b610e71565b005b3480156104f957600080fd5b50610502611063565b60405161050f9190612330565b60405180910390f35b34801561052457600080fd5b5061052d611069565b60405161053a9190612330565b60405180910390f35b34801561054f57600080fd5b5061055861106f565b60405161056591906126e7565b60405180910390f35b34801561057a57600080fd5b5061059560048036038101906105909190612402565b611098565b005b3480156105a357600080fd5b506105be60048036038101906105b99190612402565b61111b565b6040516105cb919061271b565b60405180910390f35b3480156105e057600080fd5b506105fb60048036038101906105f69190612402565b611133565b005b34801561060957600080fd5b50610624600480360381019061061f9190612402565b611172565b005b34801561063257600080fd5b5061064d60048036038101906106489190612762565b6111b1565b005b610669600480360381019061066491906125b0565b611205565b005b34801561067757600080fd5b50610680611356565b60405161068d91906126e7565b60405180910390f35b3480156106a257600080fd5b506106ab61137c565b6040516106b89190612330565b60405180910390f35b3480156106cd57600080fd5b506106e860048036038101906106e39190612402565b611382565b6040516106f591906122fc565b60405180910390f35b34801561070a57600080fd5b50610725600480360381019061072091906127cd565b6113a2565b005b34801561073357600080fd5b5061074e600480360381019061074991906123a9565b6114b8565b005b34801561075c57600080fd5b506107776004803603810190610772919061280d565b61153b565b005b60007f69bc44e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061084457507f650bd364000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610854575061085382611632565b5b9050919050565b600960009054906101000a900460ff1681565b600034116108b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a890612897565b60405180910390fd5b347f840be946bba3df0d184eb7e6cd7c9e57bb380cf6078516c7441db5709d58509860405160405180910390a2565b600c5481565b600a5481565b6108f461169c565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f679cb5acfebd038830b61daadd5f2f74e2114862b1c289a5d2db82bc6eda32a660405160405180910390a250565b61098361169c565b80600a81905550807f11cff79cc5c082b5f775ae922a2a6dc80e9f79b9207767278bdf7391db5467f760405160405180910390a250565b60085481565b6109c861169c565b60008383905011610a0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0590612903565b60405180910390fd5b600360009054906101000a900463ffffffff1663ffffffff166008548263ffffffff16610a3b9190612952565b11610a7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a72906129d2565b60405180910390fd5b60008383604051602001610a90929190612ab5565b60405160208183030381529060405280519060200120905080600260008463ffffffff168152602001908152602001600020819055508163ffffffff16817ff541dede932a20dba17286430555d7aa784b74222f2a34f107d40822f41992e360405160405180910390a350505050565b610b0861169c565b60008383905011610b4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4590612903565b60405180910390fd5b600360009054906101000a900463ffffffff1663ffffffff168163ffffffff161015610baf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba690612b25565b60405180910390fd5b60008383604051602001610bc4929190612ab5565b60405160208183030381529060405280519060200120905080600260008463ffffffff1681526020019081526020016000208190555081600360006101000a81548163ffffffff021916908363ffffffff1602179055508163ffffffff16817f36885d9a49d239da5379a6f8f9bb89273332a7e312cb5b8a2d3b0f567e8209f460405160405180910390a350505050565b6000600d54905090565b600360009054906101000a900463ffffffff1681565b610c7d61169c565b80600481905550807f06055c66c43187163b022b7d954ff32b4ba5265e175458d1b134cfe8ab72f41260405160405180910390a250565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1990612b91565b60405180910390fd5b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990612bfd565b60405180910390fd5b6000808383810190610dc49190612d6c565b91509150610dd2828261171a565b5050505050565b600e5481565b610de761169c565b610df16000611981565b565b610dfb61169c565b80600d81905550807fabd57ef278738881488128581f298faa35ba1bae2bbec9fb6e370ff60d531e4b60405160405180910390a250565b610e3a61169c565b80600881905550807f01116a77fa86522c55d40463f1b48825870a5d04ea15ca52a166d8ace7f355ff60405160405180910390a250565b60065434101580610ead57503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b610eec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee390612e14565b60405180910390fd5b60008383905011610f32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2990612e80565b60405180910390fd5b600085858585856020016020810190610f4b9190612ea0565b8660000135604051602001610f6596959493929190612f1a565b6040516020818303038152906040529050610f808183611a45565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1683600001357f3591658888eebc109961f7116a3e6aafbbeb08b55e727cf69c44d466a77a90d18787604051610fe4929190612f76565b60405180910390a48473ffffffffffffffffffffffffffffffffffffffff1663650bd3648786866040518463ffffffff1660e01b815260040161102993929190612f9a565b600060405180830381600087803b15801561104357600080fd5b505af1158015611057573d6000803e3d6000fd5b50505050505050505050565b60065481565b60045481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6110a061169c565b60648111156110e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110db90613018565b60405180910390fd5b80600781905550807fadfa8ecb21b6962ebcd0adbd9ab985b7b4c5b5eb3b0dead683171565c7bfe17160405160405180910390a250565b60026020528060005260406000206000915090505481565b61113b61169c565b80600681905550807f42dfb00d085d601e55327921154ae76c1b24270b026c5a0c51caee18eb4c401f60405160405180910390a250565b61117a61169c565b80600c81905550807f80e9dc023eeed9cbe4e886f225681c4fa94a046011c6269619c21befd6c4518160405160405180910390a250565b6111b961169c565b80600960006101000a81548160ff0219169083151502179055508015157fd06b0db8a7172c6c142c15cd90b6efb883b600b978dfca380621aa4c9f6d881560405160405180910390a250565b600960009054906101000a900460ff16611254576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124b90613084565b60405180910390fd5b600c5482829050111561129c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611293906130f0565b60405180910390fd5b600d543410156112e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d89061315c565b60405180910390fd5b34600e60008282546112f39190612952565b925050819055507ff2a50cd57a795ad452a0b8586bcd3fe8e3ee00054c01c4712655d7753539dd356004600081548092919061132e9061317c565b919050553385858534604051611349969594939291906131c4565b60405180910390a1505050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60075481565b60056020528060005260406000206000915054906101000a900460ff1681565b6113aa61169c565b80600e60008282546113bc9190613220565b9250508190555060008273ffffffffffffffffffffffffffffffffffffffff16826040516113e990613285565b60006040518083038185875af1925050503d8060008114611426576040519150601f19603f3d011682016040523d82523d6000602084013e61142b565b606091505b505090508061146f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611466906132e6565b60405180910390fd5b818373ffffffffffffffffffffffffffffffffffffffff167fcc89aff20f6022ea39ee28e42ebe0013f5e8a32d9388b49d2f6fe08563a54cdf60405160405180910390a3505050565b6114c061169c565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161152690613378565b60405180910390fd5b61153881611981565b50565b61154361169c565b600047905060008273ffffffffffffffffffffffffffffffffffffffff168260405161156e90613285565b60006040518083038185875af1925050503d80600081146115ab576040519150601f19603f3d011682016040523d82523d6000602084013e6115b0565b606091505b50509050806115f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115eb906133e4565b60405180910390fd5b7f06097061aeda806b5e9cb4133d9899f332ff0913956567fc0f7ea15e3d19947c8383604051611625929190613463565b60405180910390a1505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6116a4611f24565b73ffffffffffffffffffffffffffffffffffffffff166116c261106f565b73ffffffffffffffffffffffffffffffffffffffff1614611718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170f906134d8565b60405180910390fd5b565b60026001540361175f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175690613544565b60405180910390fd5b600260018190555060008251116117ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a290612903565b60405180910390fd5b600360009054906101000a900463ffffffff1663ffffffff168163ffffffff161161180b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611802906135d6565b60405180910390fd5b60008260405160200161181e919061367c565b60405160208183030381529060405280519060200120905080600260008463ffffffff1681526020019081526020016000208190555081600360006101000a81548163ffffffff021916908363ffffffff1602179055506000611890600e54476118889190613220565b600a54611f2c565b905060003273ffffffffffffffffffffffffffffffffffffffff16826040516118b890613285565b60006040518083038185875af1925050503d80600081146118f5576040519150601f19603f3d011682016040523d82523d6000602084013e6118fa565b606091505b505090508061193e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611935906136ea565b60405180910390fd5b8363ffffffff1682847f3dab4e75c61b76a4152c289f3c93392ddab6386b2423ffab2cee4da9fbb05c7160405160405180910390a4505050600180819055505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000816000013590506000826020016020810190611a639190612ea0565b90506000838060a00190611a779190613719565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509050600960009054906101000a900460ff16611b08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aff90613084565b60405180910390fd5b6005600084815260200190815260200160002060009054906101000a900460ff1615611b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b60906137c8565b60405180910390fd5b600360009054906101000a900463ffffffff1663ffffffff168263ffffffff161115611bca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc190613834565b60405180910390fd5b60085482600360009054906101000a900463ffffffff16611beb9190613854565b63ffffffff161115611c32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c29906138d8565b60405180910390fd5b6000815111611c76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c6d90613944565b60405180910390fd5b600260008363ffffffff1681526020019081526020016000205481604051602001611ca1919061367c565b6040516020818303038152906040528051906020012014611cf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cee906139d6565b60405180910390fd5b600085805190602001209050600060646007548451611d1691906139f6565b611d209190613a67565b905060008060005b8551811015611ea95781898060600190611d429190613a98565b83818110611d5357611d52613afb565b5b9050602002013514611e9857611df9898060400190611d729190613b2a565b83818110611d8357611d82613afb565b5b9050602002016020810190611d989190613bc6565b8a8060600190611da89190613a98565b84818110611db957611db8613afb565b5b905060200201358b8060800190611dd09190613a98565b85818110611de157611de0613afb565b5b9050602002013588611f45909392919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16868281518110611e2257611e21613afb565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614611e80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7790613c3f565b60405180910390fd5b600183611e8d9190612952565b925083831015611ea9575b80611ea29061317c565b9050611d28565b5082821015611eed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee490613cab565b60405180910390fd5b60016005600089815260200190815260200160002060006101000a81548160ff021916908315150217905550505050505050505050565b600033905090565b6000818310611f3b5781611f3d565b825b905092915050565b6000806000611f5687878787611f70565b91509150611f638161207c565b8192505050949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115611fab576000600391509150612073565b601b8560ff1614158015611fc35750601c8560ff1614155b15611fd5576000600491509150612073565b600060018787878760405160008152602001604052604051611ffa9493929190613cda565b6020604051602081039080840390855afa15801561201c573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361206a57600060019250925050612073565b80600092509250505b94509492505050565b600060048111156120905761208f613d1f565b5b8160048111156120a3576120a2613d1f565b5b031561224557600160048111156120bd576120bc613d1f565b5b8160048111156120d0576120cf613d1f565b5b03612110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161210790613d9a565b60405180910390fd5b6002600481111561212457612123613d1f565b5b81600481111561213757612136613d1f565b5b03612177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161216e90613e06565b60405180910390fd5b6003600481111561218b5761218a613d1f565b5b81600481111561219e5761219d613d1f565b5b036121de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121d590613e98565b60405180910390fd5b6004808111156121f1576121f0613d1f565b5b81600481111561220457612203613d1f565b5b03612244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223b90613f2a565b60405180910390fd5b5b50565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6122918161225c565b811461229c57600080fd5b50565b6000813590506122ae81612288565b92915050565b6000602082840312156122ca576122c9612252565b5b60006122d88482850161229f565b91505092915050565b60008115159050919050565b6122f6816122e1565b82525050565b600060208201905061231160008301846122ed565b92915050565b6000819050919050565b61232a81612317565b82525050565b60006020820190506123456000830184612321565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006123768261234b565b9050919050565b6123868161236b565b811461239157600080fd5b50565b6000813590506123a38161237d565b92915050565b6000602082840312156123bf576123be612252565b5b60006123cd84828501612394565b91505092915050565b6123df81612317565b81146123ea57600080fd5b50565b6000813590506123fc816123d6565b92915050565b60006020828403121561241857612417612252565b5b6000612426848285016123ed565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126124545761245361242f565b5b8235905067ffffffffffffffff81111561247157612470612434565b5b60208301915083602082028301111561248d5761248c612439565b5b9250929050565b600063ffffffff82169050919050565b6124ad81612494565b81146124b857600080fd5b50565b6000813590506124ca816124a4565b92915050565b6000806000604084860312156124e9576124e8612252565b5b600084013567ffffffffffffffff81111561250757612506612257565b5b6125138682870161243e565b93509350506020612526868287016124bb565b9150509250925092565b61253981612494565b82525050565b60006020820190506125546000830184612530565b92915050565b60008083601f8401126125705761256f61242f565b5b8235905067ffffffffffffffff81111561258d5761258c612434565b5b6020830191508360018202830111156125a9576125a8612439565b5b9250929050565b6000806000604084860312156125c9576125c8612252565b5b60006125d786828701612394565b935050602084013567ffffffffffffffff8111156125f8576125f7612257565b5b6126048682870161255a565b92509250509250925092565b600080fd5b600060c0828403121561262b5761262a612610565b5b81905092915050565b6000806000806000608086880312156126505761264f612252565b5b600061265e88828901612394565b955050602061266f88828901612394565b945050604086013567ffffffffffffffff8111156126905761268f612257565b5b61269c8882890161255a565b9350935050606086013567ffffffffffffffff8111156126bf576126be612257565b5b6126cb88828901612615565b9150509295509295909350565b6126e18161236b565b82525050565b60006020820190506126fc60008301846126d8565b92915050565b6000819050919050565b61271581612702565b82525050565b6000602082019050612730600083018461270c565b92915050565b61273f816122e1565b811461274a57600080fd5b50565b60008135905061275c81612736565b92915050565b60006020828403121561277857612777612252565b5b60006127868482850161274d565b91505092915050565b600061279a8261234b565b9050919050565b6127aa8161278f565b81146127b557600080fd5b50565b6000813590506127c7816127a1565b92915050565b600080604083850312156127e4576127e3612252565b5b60006127f2858286016127b8565b9250506020612803858286016123ed565b9150509250929050565b60006020828403121561282357612822612252565b5b6000612831848285016127b8565b91505092915050565b600082825260208201905092915050565b7f4272696467653a206d75737420656e646f77206e6f6e7a65726f000000000000600082015250565b6000612881601a8361283a565b915061288c8261284b565b602082019050919050565b600060208201905081810360008301526128b081612874565b9050919050565b7f4272696467653a20656d7074792076616c696461746f72207365740000000000600082015250565b60006128ed601b8361283a565b91506128f8826128b7565b602082019050919050565b6000602082019050818103600083015261291c816128e0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061295d82612317565b915061296883612317565b92508282019050808211156129805761297f612923565b5b92915050565b7f4272696467653a2073657420697320696e616374697665000000000000000000600082015250565b60006129bc60178361283a565b91506129c782612986565b602082019050919050565b600060208201905081810360008301526129eb816129af565b9050919050565b600082825260208201905092915050565b6000819050919050565b612a168161236b565b82525050565b6000612a288383612a0d565b60208301905092915050565b6000612a436020840184612394565b905092915050565b6000602082019050919050565b6000612a6483856129f2565b9350612a6f82612a03565b8060005b85811015612aa857612a858284612a34565b612a8f8882612a1c565b9750612a9a83612a4b565b925050600181019050612a73565b5085925050509392505050565b60006020820190508181036000830152612ad0818486612a58565b90509392505050565b7f4272696467653a2073657420697320686973746f726963000000000000000000600082015250565b6000612b0f60178361283a565b9150612b1a82612ad9565b602082019050919050565b60006020820190508181036000830152612b3e81612b02565b9050919050565b7f4272696467653a206f6e6c79206272696467652063616e2063616c6c00000000600082015250565b6000612b7b601c8361283a565b9150612b8682612b45565b602082019050919050565b60006020820190508181036000830152612baa81612b6e565b9050919050565b7f4272696467653a20736f75726365206d7573742062652070616c6c6574000000600082015250565b6000612be7601d8361283a565b9150612bf282612bb1565b602082019050919050565b60006020820190508181036000830152612c1681612bda565b9050919050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612c6682612c1d565b810181811067ffffffffffffffff82111715612c8557612c84612c2e565b5b80604052505050565b6000612c98612248565b9050612ca48282612c5d565b919050565b600067ffffffffffffffff821115612cc457612cc3612c2e565b5b602082029050602081019050919050565b6000612ce8612ce384612ca9565b612c8e565b90508083825260208201905060208402830185811115612d0b57612d0a612439565b5b835b81811015612d345780612d208882612394565b845260208401935050602081019050612d0d565b5050509392505050565b600082601f830112612d5357612d5261242f565b5b8135612d63848260208601612cd5565b91505092915050565b60008060408385031215612d8357612d82612252565b5b600083013567ffffffffffffffff811115612da157612da0612257565b5b612dad85828601612d3e565b9250506020612dbe858286016124bb565b9150509250929050565b7f4272696467653a206d75737420737570706c7920627269646765206665650000600082015250565b6000612dfe601e8361283a565b9150612e0982612dc8565b602082019050919050565b60006020820190508181036000830152612e2d81612df1565b9050919050565b7f4272696467653a20656d707479206d6573736167650000000000000000000000600082015250565b6000612e6a60158361283a565b9150612e7582612e34565b602082019050919050565b60006020820190508181036000830152612e9981612e5d565b9050919050565b600060208284031215612eb657612eb5612252565b5b6000612ec4848285016124bb565b91505092915050565b600082825260208201905092915050565b82818337600083830152505050565b6000612ef98385612ecd565b9350612f06838584612ede565b612f0f83612c1d565b840190509392505050565b600060a082019050612f2f60008301896126d8565b612f3c60208301886126d8565b8181036040830152612f4f818688612eed565b9050612f5e6060830185612530565b612f6b6080830184612321565b979650505050505050565b60006020820190508181036000830152612f91818486612eed565b90509392505050565b6000604082019050612faf60008301866126d8565b8181036020830152612fc2818486612eed565b9050949350505050565b7f4272696467653a2070657263656e74206d757374206265203c3d203130300000600082015250565b6000613002601e8361283a565b915061300d82612fcc565b602082019050919050565b6000602082019050818103600083015261303181612ff5565b9050919050565b7f4272696467653a2062726964676520696e616374697665000000000000000000600082015250565b600061306e60178361283a565b915061307982613038565b602082019050919050565b6000602082019050818103600083015261309d81613061565b9050919050565b7f4272696467653a206d73672065786365656473206d6178206c656e6774680000600082015250565b60006130da601e8361283a565b91506130e5826130a4565b602082019050919050565b60006020820190508181036000830152613109816130cd565b9050919050565b7f4272696467653a20696e73756666696369656e74206d65737361676520666565600082015250565b600061314660208361283a565b915061315182613110565b602082019050919050565b6000602082019050818103600083015261317581613139565b9050919050565b600061318782612317565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036131b9576131b8612923565b5b600182019050919050565b600060a0820190506131d96000830189612321565b6131e660208301886126d8565b6131f360408301876126d8565b8181036060830152613206818587612eed565b90506132156080830184612321565b979650505050505050565b600061322b82612317565b915061323683612317565b925082820390508181111561324e5761324d612923565b5b92915050565b600081905092915050565b50565b600061326f600083613254565b915061327a8261325f565b600082019050919050565b600061329082613262565b9150819050919050565b7f4272696467653a204661696c656420746f2073656e64206d7367206665657300600082015250565b60006132d0601f8361283a565b91506132db8261329a565b602082019050919050565b600060208201905081810360008301526132ff816132c3565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061336260268361283a565b915061336d82613306565b604082019050919050565b6000602082019050818103600083015261339181613355565b9050919050565b7f4272696467653a206661696c656420746f2073656e6420457468657200000000600082015250565b60006133ce601c8361283a565b91506133d982613398565b602082019050919050565b600060208201905081810360008301526133fd816133c1565b9050919050565b6000819050919050565b600061342961342461341f8461234b565b613404565b61234b565b9050919050565b600061343b8261340e565b9050919050565b600061344d82613430565b9050919050565b61345d81613442565b82525050565b60006040820190506134786000830185613454565b6134856020830184612321565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006134c260208361283a565b91506134cd8261348c565b602082019050919050565b600060208201905081810360008301526134f1816134b5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061352e601f8361283a565b9150613539826134f8565b602082019050919050565b6000602082019050818103600083015261355d81613521565b9050919050565b7f4272696467653a2076616c696461746f7220736574206964207265706c61796560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b60006135c060218361283a565b91506135cb82613564565b604082019050919050565b600060208201905081810360008301526135ef816135b3565b9050919050565b600081519050919050565b6000819050602082019050919050565b6000602082019050919050565b6000613629826135f6565b61363381856129f2565b935061363e83613601565b8060005b8381101561366f5781516136568882612a1c565b975061366183613611565b925050600181019050613642565b5085935050505092915050565b60006020820190508181036000830152613696818461361e565b905092915050565b7f4272696467653a204661696c656420746f2073656e6420726577617264000000600082015250565b60006136d4601d8361283a565b91506136df8261369e565b602082019050919050565b60006020820190508181036000830152613703816136c7565b9050919050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126137365761373561370a565b5b80840192508235915067ffffffffffffffff8211156137585761375761370f565b5b60208301925060208202360383131561377457613773613714565b5b509250929050565b7f4272696467653a206576656e744964207265706c617965640000000000000000600082015250565b60006137b260188361283a565b91506137bd8261377c565b602082019050919050565b600060208201905081810360008301526137e1816137a5565b9050919050565b7f4272696467653a206675747572652076616c696461746f722073657400000000600082015250565b600061381e601c8361283a565b9150613829826137e8565b602082019050919050565b6000602082019050818103600083015261384d81613811565b9050919050565b600061385f82612494565b915061386a83612494565b9250828203905063ffffffff81111561388657613885612923565b5b92915050565b7f4272696467653a20657870697265642070726f6f660000000000000000000000600082015250565b60006138c260158361283a565b91506138cd8261388c565b602082019050919050565b600060208201905081810360008301526138f1816138b5565b9050919050565b7f4272696467653a20696e76616c69642076616c696461746f7220736574000000600082015250565b600061392e601d8361283a565b9150613939826138f8565b602082019050919050565b6000602082019050818103600083015261395d81613921565b9050919050565b7f4272696467653a20756e65787065637465642076616c696461746f722064696760008201527f6573740000000000000000000000000000000000000000000000000000000000602082015250565b60006139c060238361283a565b91506139cb82613964565b604082019050919050565b600060208201905081810360008301526139ef816139b3565b9050919050565b6000613a0182612317565b9150613a0c83612317565b9250828202613a1a81612317565b91508282048414831517613a3157613a30612923565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613a7282612317565b9150613a7d83612317565b925082613a8d57613a8c613a38565b5b828204905092915050565b60008083356001602003843603038112613ab557613ab461370a565b5b80840192508235915067ffffffffffffffff821115613ad757613ad661370f565b5b602083019250602082023603831315613af357613af2613714565b5b509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083356001602003843603038112613b4757613b4661370a565b5b80840192508235915067ffffffffffffffff821115613b6957613b6861370f565b5b602083019250602082023603831315613b8557613b84613714565b5b509250929050565b600060ff82169050919050565b613ba381613b8d565b8114613bae57600080fd5b50565b600081359050613bc081613b9a565b92915050565b600060208284031215613bdc57613bdb612252565b5b6000613bea84828501613bb1565b91505092915050565b7f4272696467653a207369676e617475726520696e76616c696400000000000000600082015250565b6000613c2960198361283a565b9150613c3482613bf3565b602082019050919050565b60006020820190508181036000830152613c5881613c1c565b9050919050565b7f4272696467653a206e6f7420656e6f756768207369676e617475726573000000600082015250565b6000613c95601d8361283a565b9150613ca082613c5f565b602082019050919050565b60006020820190508181036000830152613cc481613c88565b9050919050565b613cd481613b8d565b82525050565b6000608082019050613cef600083018761270c565b613cfc6020830186613ccb565b613d09604083018561270c565b613d16606083018461270c565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000613d8460188361283a565b9150613d8f82613d4e565b602082019050919050565b60006020820190508181036000830152613db381613d77565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000613df0601f8361283a565b9150613dfb82613dba565b602082019050919050565b60006020820190508181036000830152613e1f81613de3565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000613e8260228361283a565b9150613e8d82613e26565b604082019050919050565b60006020820190508181036000830152613eb181613e75565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000613f1460228361283a565b9150613f1f82613eb8565b604082019050919050565b60006020820190508181036000830152613f4381613f07565b905091905056fea2646970667358221220f9a8d1b86a248b8c1da50bc478fabe85896722e6801967a7060316a27baa54eb64736f6c63430008110033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.