Contract 0x2d493cde51adc74D4494b3dC146759cF32957A23 2

Contract Overview

Balance:
30.650751563500550001 AVAX
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xf82aa9cc2e74c26240b35e844b5fdfd6f30e1e5584d1790c59ab83a5bc760888Deposit For140890592022-09-29 0:26:2519 hrs 41 mins ago0xfe5ee99fdbccfada674a3b85ef653b3ce4656e13 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230.3 AVAX0.001388452 26
0xc99b246bf037b1ec8ccc8096a625afab36d4287f5ac182629dea9685707f1c110xb1a62e72133835422022-09-11 14:38:5118 days 5 hrs ago0xfd2d1f0b6211ab230db6f93153c7606fda3a18f8 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.006393634456 35.817476482
0x2920cdb47c1cff3a0709b9449e4e7db3fecc4ec5d81de64b419fb7cc293b210a0xb1a62e72133834122022-09-11 14:33:2918 days 5 hrs ago0xfd2d1f0b6211ab230db6f93153c7606fda3a18f8 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.0072749064 37.2
0x9c0ab715b02c0107571aaac68df56e56a020cc07c760e423a1ca4f5db759b12c0xb1a62e72133833822022-09-11 14:32:1618 days 5 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.00727446 37.2
0xb65c54d5040ddc51d364c876e124f0bc420af24cb8ad4ef83d972b61a88109e30xb1a62e72132729102022-09-08 1:05:4821 days 19 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.00628914528 32.16
0xce5f25adc339d0bae7e61d6aa0caa66f7390ff5080f02732e1290f7788f519f30xb1a62e72132100952022-09-06 3:02:3823 days 17 hrs ago0xfd2d1f0b6211ab230db6f93153c7606fda3a18f8 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.0055683888 31.2
0xd6d8a6a8db37f145b76d2c4eec629e8d0900d98978c5fc4665705f97b3e2bead0xb1a62e72131803862022-09-05 5:23:1824 days 14 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.011367725 25
0xce39bfa8199c9abd5a8dcc5409435f0e447e3d1055696df611f17b5227a744ab0xb1a62e72131803102022-09-05 5:18:4224 days 14 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.0116674 25
0xdb77883e32ee9ae5eafaa7a47d8492cd0fcf42103da2ac9dec979c3a8cb57f070xb1a62e72131800382022-09-05 5:04:3024 days 15 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.011670525 25
0x382b02c7729dfb76b0ea0a8b43abf4036cc3e3f96f5972d5aceb3b0385b6c0ac0xb1a62e72131797672022-09-05 4:50:2624 days 15 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.011227225 25
0xe7ea79440e03570632cd552830124cd8d360f97f7509f4e30a0f7a07b510d6850xb1a62e72131797522022-09-05 4:49:2824 days 15 hrs ago0xfd2d1f0b6211ab230db6f93153c7606fda3a18f8 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.011227525 25
0x8fd9d3678f627b0bd4fe76bd1e631d727b61342981d6869c6a441eef63ded4960xb1a62e72131796922022-09-05 4:45:3824 days 15 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.011297225 25
0x1e2b39fa537493a2fd525d090ab520262b254fce4e571204416fed0ed16cef480xb1a62e72131796492022-09-05 4:43:5124 days 15 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.011721 25
0x281f52bedcfb39e0623de3ace0010a4cf3915f8fa3d3c89d805e8860e4fd09f90xb1a62e72131792822022-09-05 4:24:5324 days 15 hrs ago0xfd2d1f0b6211ab230db6f93153c7606fda3a18f8 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.01181435 25
0x11f203525a37367923b3a7a7d5d0c878cc7759bdf3756f3221976a358bf9c6e00xb1a62e72131719402022-09-04 21:18:1724 days 22 hrs ago0xfd2d1f0b6211ab230db6f93153c7606fda3a18f8 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.01128165 25
0xc364bfb718f0e98e822255a7ac9694a5323c1af2cf93b2012866fe6eb26d78190xb1a62e72130665392022-09-01 12:28:3928 days 7 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.0061004112 31.2
0x356f409ff81a5408e01698b9eb732fd0d0f84006ffdb6b3ca53a14eabe5665900xb1a62e72130306292022-08-31 13:32:0129 days 6 hrs ago0xfd2d1f0b6211ab230db6f93153c7606fda3a18f8 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.007232665008 36.984
0xe74555b538639050601aa69f08a1e84509d3ae19861e02e08a521bd816cf947d0xb1a62e72129586072022-08-29 4:54:0331 days 15 hrs ago0xfd2d1f0b6211ab230db6f93153c7606fda3a18f8 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.006229975 25
0x56925512e51ce4ea3fb053186875af63c3ff5ff5da7fb928a0bab6429c67b54e0xb1a62e72129572432022-08-29 3:48:0931 days 16 hrs ago0xfd2d1f0b6211ab230db6f93153c7606fda3a18f8 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.006229775 25
0xafb1a126f80c7c17923ce4e768fd0a96804792ae5ffbebdfef252fb8ddb587190xb1a62e72129572252022-08-29 3:47:2531 days 16 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.006229775 25
0x1d88af083f841d6ef50a4f9e58ca703bba94e80a29e413b503e5c6ab5c066ffa0xb1a62e72129572082022-08-29 3:46:4531 days 16 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.006229975 25
0xb1e292a9d586b169b8d47b190a3c7a48edefa24b9e2a7e4ddf461651ceb961a30xb1a62e72129571852022-08-29 3:45:4531 days 16 hrs ago0xfd2d1f0b6211ab230db6f93153c7606fda3a18f8 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.006229775 25
0xa41da9c3ccd5c2e850c206ce14eead47098add9509e2d484622a584c35dc85980xb1a62e72129571662022-08-29 3:45:0631 days 16 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.006299775 25
0xd18719e073e76129ae329a063db34ef4512fd105e4bf9057306700f71042d6ce0xb1a62e72128385122022-08-25 5:30:1635 days 14 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.0115436 25
0x6637e2482dafc706008ffc4bb3f1eabbe206da29eb1b2ab8967d07c5e1d42ec40xb1a62e72128384912022-08-25 5:28:5135 days 14 hrs ago0x1a4b71942e08e76c32317a009280b502db606396 IN 0x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX0.00439155 25
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xf82aa9cc2e74c26240b35e844b5fdfd6f30e1e5584d1790c59ab83a5bc760888140890592022-09-29 0:26:2519 hrs 41 mins ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x4fe63e63d960a661c391fd332f73395270dbbf990 AVAX
0xf82aa9cc2e74c26240b35e844b5fdfd6f30e1e5584d1790c59ab83a5bc760888140890592022-09-29 0:26:2519 hrs 41 mins ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x4fe63e63d960a661c391fd332f73395270dbbf990 AVAX
0xf82aa9cc2e74c26240b35e844b5fdfd6f30e1e5584d1790c59ab83a5bc760888140890592022-09-29 0:26:2519 hrs 41 mins ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x4fe63e63d960a661c391fd332f73395270dbbf990 AVAX
0xb923061d4c2e4ca0da4ce38e5ca433f580cf60a30a8b238df30dc74ab81f2a95140462582022-09-27 23:12:571 day 20 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x31638c4ae939db4cdfda003b7bc1d205d13d11a60 AVAX
0xb923061d4c2e4ca0da4ce38e5ca433f580cf60a30a8b238df30dc74ab81f2a95140462582022-09-27 23:12:571 day 20 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x31638c4ae939db4cdfda003b7bc1d205d13d11a60 AVAX
0xb923061d4c2e4ca0da4ce38e5ca433f580cf60a30a8b238df30dc74ab81f2a95140462582022-09-27 23:12:571 day 20 hrs ago 0x409893be00ab9cc726a2aab7ffb08e33009b3c900x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX
0x8167e3fe23baf665380c713905e69f5d10505bbc42dbf2358c96cb39e62eb145137679962022-09-21 19:45:368 days 22 mins ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x31638c4ae939db4cdfda003b7bc1d205d13d11a60 AVAX
0x8167e3fe23baf665380c713905e69f5d10505bbc42dbf2358c96cb39e62eb145137679962022-09-21 19:45:368 days 22 mins ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x31638c4ae939db4cdfda003b7bc1d205d13d11a60 AVAX
0x8167e3fe23baf665380c713905e69f5d10505bbc42dbf2358c96cb39e62eb145137679962022-09-21 19:45:368 days 22 mins ago 0x409893be00ab9cc726a2aab7ffb08e33009b3c900x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX
0xfbbd1cd82fde3b7d04b585dbcad0b08ea6384c78ff83d05bee5fbd1282ba4faf135501002022-09-15 19:16:4114 days 51 mins ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x31638c4ae939db4cdfda003b7bc1d205d13d11a60 AVAX
0xfbbd1cd82fde3b7d04b585dbcad0b08ea6384c78ff83d05bee5fbd1282ba4faf135501002022-09-15 19:16:4114 days 51 mins ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x31638c4ae939db4cdfda003b7bc1d205d13d11a60 AVAX
0xfbbd1cd82fde3b7d04b585dbcad0b08ea6384c78ff83d05bee5fbd1282ba4faf135501002022-09-15 19:16:4114 days 51 mins ago 0x409893be00ab9cc726a2aab7ffb08e33009b3c900x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX
0xc99b246bf037b1ec8ccc8096a625afab36d4287f5ac182629dea9685707f1c11133835422022-09-11 14:38:5118 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x1e4d8ebd5071d117bcf351e3d53e34620d3ac1900 AVAX
0xc99b246bf037b1ec8ccc8096a625afab36d4287f5ac182629dea9685707f1c11133835422022-09-11 14:38:5118 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a23 0x7a95fa73250dc53556d264522150a940d4c502380 AVAX
0xc99b246bf037b1ec8ccc8096a625afab36d4287f5ac182629dea9685707f1c11133835422022-09-11 14:38:5118 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x1e4d8ebd5071d117bcf351e3d53e34620d3ac1900 AVAX
0xc99b246bf037b1ec8ccc8096a625afab36d4287f5ac182629dea9685707f1c11133835422022-09-11 14:38:5118 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX
0xc99b246bf037b1ec8ccc8096a625afab36d4287f5ac182629dea9685707f1c11133835422022-09-11 14:38:5118 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x1e4d8ebd5071d117bcf351e3d53e34620d3ac1900 AVAX
0xc99b246bf037b1ec8ccc8096a625afab36d4287f5ac182629dea9685707f1c11133835422022-09-11 14:38:5118 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x31638c4ae939db4cdfda003b7bc1d205d13d11a60 AVAX
0x2920cdb47c1cff3a0709b9449e4e7db3fecc4ec5d81de64b419fb7cc293b210a133834122022-09-11 14:33:2918 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x1e4d8ebd5071d117bcf351e3d53e34620d3ac1900 AVAX
0x2920cdb47c1cff3a0709b9449e4e7db3fecc4ec5d81de64b419fb7cc293b210a133834122022-09-11 14:33:2918 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a23 0x7a95fa73250dc53556d264522150a940d4c502380 AVAX
0x2920cdb47c1cff3a0709b9449e4e7db3fecc4ec5d81de64b419fb7cc293b210a133834122022-09-11 14:33:2918 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x1e4d8ebd5071d117bcf351e3d53e34620d3ac1900 AVAX
0x2920cdb47c1cff3a0709b9449e4e7db3fecc4ec5d81de64b419fb7cc293b210a133834122022-09-11 14:33:2918 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x2d493cde51adc74d4494b3dc146759cf32957a230 AVAX
0x2920cdb47c1cff3a0709b9449e4e7db3fecc4ec5d81de64b419fb7cc293b210a133834122022-09-11 14:33:2918 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x1e4d8ebd5071d117bcf351e3d53e34620d3ac1900 AVAX
0x2920cdb47c1cff3a0709b9449e4e7db3fecc4ec5d81de64b419fb7cc293b210a133834122022-09-11 14:33:2918 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x31638c4ae939db4cdfda003b7bc1d205d13d11a60 AVAX
0x9c0ab715b02c0107571aaac68df56e56a020cc07c760e423a1ca4f5db759b12c133833822022-09-11 14:32:1618 days 5 hrs ago 0x2d493cde51adc74d4494b3dc146759cf32957a230x1e4d8ebd5071d117bcf351e3d53e34620d3ac1900 AVAX
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RelayHub

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 21 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        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 2 of 21 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)

pragma solidity ^0.8.0;

import "../utils/introspection/IERC165.sol";

File 3 of 21 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 4 of 21 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 5 of 21 : 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;
    }
}

File 6 of 21 : 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 7 of 21 : ERC165Checker.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Checker.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Library used to query support of an interface declared via {IERC165}.
 *
 * Note that these functions return the actual result of the query: they do not
 * `revert` if an interface is not supported. It is up to the caller to decide
 * what to do in these cases.
 */
library ERC165Checker {
    // As per the EIP-165 spec, no interface should ever match 0xffffffff
    bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;

    /**
     * @dev Returns true if `account` supports the {IERC165} interface,
     */
    function supportsERC165(address account) internal view returns (bool) {
        // Any contract that implements ERC165 must explicitly indicate support of
        // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
        return
            _supportsERC165Interface(account, type(IERC165).interfaceId) &&
            !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
    }

    /**
     * @dev Returns true if `account` supports the interface defined by
     * `interfaceId`. Support for {IERC165} itself is queried automatically.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
        // query support of both ERC165 as per the spec and support of _interfaceId
        return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);
    }

    /**
     * @dev Returns a boolean array where each value corresponds to the
     * interfaces passed in and whether they're supported or not. This allows
     * you to batch check interfaces for a contract where your expectation
     * is that some interfaces may not be supported.
     *
     * See {IERC165-supportsInterface}.
     *
     * _Available since v3.4._
     */
    function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)
        internal
        view
        returns (bool[] memory)
    {
        // an array of booleans corresponding to interfaceIds and whether they're supported or not
        bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);

        // query support of ERC165 itself
        if (supportsERC165(account)) {
            // query support of each interface in interfaceIds
            for (uint256 i = 0; i < interfaceIds.length; i++) {
                interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);
            }
        }

        return interfaceIdsSupported;
    }

    /**
     * @dev Returns true if `account` supports all the interfaces defined in
     * `interfaceIds`. Support for {IERC165} itself is queried automatically.
     *
     * Batch-querying can lead to gas savings by skipping repeated checks for
     * {IERC165} support.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
        // query support of ERC165 itself
        if (!supportsERC165(account)) {
            return false;
        }

        // query support of each interface in _interfaceIds
        for (uint256 i = 0; i < interfaceIds.length; i++) {
            if (!_supportsERC165Interface(account, interfaceIds[i])) {
                return false;
            }
        }

        // all interfaces supported
        return true;
    }

    /**
     * @notice Query if a contract implements an interface, does not check ERC165 support
     * @param account The address of the contract to query for support of an interface
     * @param interfaceId The interface identifier, as specified in ERC-165
     * @return true if the contract at account indicates support of the interface with
     * identifier interfaceId, false otherwise
     * @dev Assumes that account contains a contract that supports ERC165, otherwise
     * the behavior of this method is undefined. This precondition can be checked
     * with {supportsERC165}.
     * Interface identification is specified in ERC-165.
     */
    function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {
        bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);
        (bool success, bytes memory result) = account.staticcall{gas: 30000}(encodedParams);
        if (result.length < 32) return false;
        return success && abi.decode(result, (bool));
    }
}

File 8 of 21 : 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 21 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @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 / b + (a % b == 0 ? 0 : 1);
    }
}

File 10 of 21 : RelayHub.sol
pragma solidity ^0.8.0;
pragma abicoder v2;

/* solhint-disable avoid-low-level-calls */
/* solhint-disable no-inline-assembly */
/* solhint-disable not-rely-on-time */
/* solhint-disable avoid-tx-origin */
/* solhint-disable bracket-align */
// SPDX-License-Identifier: GPL-3.0-only

import "./utils/MinLibBytes.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "./utils/GsnUtils.sol";
import "./utils/GsnEip712Library.sol";
import "./utils/RelayHubValidator.sol";
import "./utils/GsnTypes.sol";
import "./interfaces/IRelayHub.sol";
import "./interfaces/IPaymaster.sol";
import "./forwarder/IForwarder.sol";
import "./interfaces/IStakeManager.sol";
import "./interfaces/IRelayRegistrar.sol";
import "./interfaces/IStakeManager.sol";

/**
 * @title The RelayHub Implementation
 * @notice This contract implements the `IRelayHub` interface for the EVM-compatible networks.
 */
contract RelayHub is IRelayHub, Ownable, ERC165 {
    using ERC165Checker for address;
    using Address for address;

    address private constant DRY_RUN_ADDRESS = 0x0000000000000000000000000000000000000000;

    /// @inheritdoc IRelayHub
    function versionHub() override virtual public pure returns (string memory){
        return "3.0.0-beta.0+opengsn.hub.irelayhub";
    }

    IStakeManager internal immutable stakeManager;
    address internal immutable penalizer;
    address internal immutable batchGateway;
    address internal immutable relayRegistrar;

    RelayHubConfig internal config;

    /// @inheritdoc IRelayHub
    function getConfiguration() public override view returns (RelayHubConfig memory) {
        return config;
    }

    /// @inheritdoc IRelayHub
    function setConfiguration(RelayHubConfig memory _config) public override onlyOwner {
        require(_config.devFee < 100, "dev fee too high");
        config = _config;
        emit RelayHubConfigured(config);
    }

    // maps ERC-20 token address to a minimum stake for it
    mapping(IERC20 => uint256) internal minimumStakePerToken;

    /// @inheritdoc IRelayHub
    function setMinimumStakes(IERC20[] memory token, uint256[] memory minimumStake) public override onlyOwner {
        require(token.length == minimumStake.length, "setMinimumStakes: wrong length");
        for (uint256 i = 0; i < token.length; i++) {
            minimumStakePerToken[token[i]] = minimumStake[i];
            emit StakingTokenDataChanged(address(token[i]), minimumStake[i]);
        }
    }

    // maps relay worker's address to its manager's address
    mapping(address => address) internal workerToManager;

    // maps relay managers to the number of their workers
    mapping(address => uint256) internal workerCount;

    mapping(address => uint256) internal balances;

    uint256 internal immutable creationBlock;
    uint256 internal deprecationTime = type(uint256).max;

    constructor (
        IStakeManager _stakeManager,
        address _penalizer,
        address _batchGateway,
        address _relayRegistrar,
        RelayHubConfig memory _config
    ) {
        creationBlock = block.number;
        stakeManager = _stakeManager;
        penalizer = _penalizer;
        batchGateway = _batchGateway;
        relayRegistrar = _relayRegistrar;
        setConfiguration(_config);
    }

    /// @inheritdoc IRelayHub
    function getCreationBlock() external override virtual view returns (uint256){
        return creationBlock;
    }

    /// @inheritdoc IRelayHub
    function getDeprecationTime() external override view returns (uint256) {
        return deprecationTime;
    }

    /// @inheritdoc IRelayHub
    function getStakeManager() external override view returns (IStakeManager) {
        return stakeManager;
    }

    /// @inheritdoc IRelayHub
    function getPenalizer() external override view returns (address) {
        return penalizer;
    }

    /// @inheritdoc IRelayHub
    function getBatchGateway() external override view returns (address) {
        return batchGateway;
    }

    /// @inheritdoc IRelayHub
    function getRelayRegistrar() external override view returns (address) {
        return relayRegistrar;
    }

    /// @inheritdoc IRelayHub
    function getMinimumStakePerToken(IERC20 token) external override view returns (uint256) {
        return minimumStakePerToken[token];
    }

    /// @inheritdoc IRelayHub
    function getWorkerManager(address worker) external override view returns (address) {
        return workerToManager[worker];
    }

    /// @inheritdoc IRelayHub
    function getWorkerCount(address manager) external override view returns (uint256) {
        return workerCount[manager];
    }

    /// @inheritdoc IERC165
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
        return interfaceId == type(IRelayHub).interfaceId ||
            interfaceId == type(Ownable).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /// @inheritdoc IRelayHub
    function onRelayServerRegistered(address relayManager) external override {
        require(msg.sender == relayRegistrar, "caller is not relay registrar");
        verifyRelayManagerStaked(relayManager);
        require(workerCount[relayManager] > 0, "no relay workers");
        stakeManager.updateRelayKeepaliveTime(relayManager);
    }

    /// @inheritdoc IRelayHub
    function addRelayWorkers(address[] calldata newRelayWorkers) external override {
        address relayManager = msg.sender;
        uint256 newWorkerCount = workerCount[relayManager] + newRelayWorkers.length;
        workerCount[relayManager] = newWorkerCount;
        require(newWorkerCount <= config.maxWorkerCount, "too many workers");

        verifyRelayManagerStaked(relayManager);

        for (uint256 i = 0; i < newRelayWorkers.length; i++) {
            require(workerToManager[newRelayWorkers[i]] == address(0), "this worker has a manager");
            workerToManager[newRelayWorkers[i]] = relayManager;
        }

        emit RelayWorkersAdded(relayManager, newRelayWorkers, newWorkerCount);
    }

    /// @inheritdoc IRelayHub
    function depositFor(address target) public virtual override payable {
        require(target.supportsInterface(type(IPaymaster).interfaceId), "target is not a valid IPaymaster");
        uint256 amount = msg.value;

        balances[target] = balances[target] + amount;

        emit Deposited(target, msg.sender, amount);
    }

    /// @inheritdoc IRelayHub
    function balanceOf(address target) external override view returns (uint256) {
        return balances[target];
    }

    /// @inheritdoc IRelayHub
    function withdraw(address payable dest, uint256 amount) public override {
        uint256[] memory amounts = new uint256[](1);
        address payable[] memory destinations = new address payable[](1);
        amounts[0] = amount;
        destinations[0] = dest;
        withdrawMultiple(destinations, amounts);
    }

    /// @inheritdoc IRelayHub
    function withdrawMultiple(address payable[] memory dest, uint256[] memory amount) public override {
        address payable account = payable(msg.sender);
        for (uint256 i = 0; i < amount.length; i++) {
            uint256 balance = balances[account];
            require(balance >= amount[i], "insufficient funds");
            balances[account] = balance - amount[i];
            (bool success, ) = dest[i].call{value: amount[i]}("");
            require(success, "Transfer failed.");
            emit Withdrawn(account, dest[i], amount[i]);
        }
    }

    function verifyGasAndDataLimits(
        uint256 maxAcceptanceBudget,
        GsnTypes.RelayRequest calldata relayRequest,
        uint256 initialGasLeft
    )
    private
    view
    returns (IPaymaster.GasAndDataLimits memory gasAndDataLimits, uint256 maxPossibleGas) {
        gasAndDataLimits =
            IPaymaster(relayRequest.relayData.paymaster).getGasAndDataLimits{gas:50000}();
        require(msg.data.length <= gasAndDataLimits.calldataSizeLimit, "msg.data exceeded limit" );

        require(maxAcceptanceBudget >= gasAndDataLimits.acceptanceBudget, "acceptance budget too high");
        require(gasAndDataLimits.acceptanceBudget >= gasAndDataLimits.preRelayedCallGasLimit, "acceptance budget too low");

        maxPossibleGas = relayRequest.relayData.transactionCalldataGasUsed + initialGasLeft;

        uint256 maxPossibleCharge = calculateCharge(
            maxPossibleGas,
            relayRequest.relayData
        );

        // We don't yet know how much gas will be used by the recipient, so we make sure there are enough funds to pay
        // for the maximum possible charge.
        require(maxPossibleCharge <= balances[relayRequest.relayData.paymaster],
            "Paymaster balance too low");
    }

    struct RelayCallData {
        bool success;
        bytes4 functionSelector;
        uint256 initialGasLeft;
        bytes recipientContext;
        bytes relayedCallReturnValue;
        IPaymaster.GasAndDataLimits gasAndDataLimits;
        RelayCallStatus status;
        uint256 innerGasUsed;
        uint256 maxPossibleGas;
        uint256 innerGasLimit;
        uint256 gasBeforeInner;
        uint256 gasUsed;
        uint256 devCharge;
        bytes retData;
        address relayManager;
        bytes32 relayRequestId;
    }

    /// @inheritdoc IRelayHub
    function relayCall(
        uint256 maxAcceptanceBudget,
        GsnTypes.RelayRequest calldata relayRequest,
        bytes calldata signature,
        bytes calldata approvalData
    )
    external
    override
    returns (
        bool paymasterAccepted,
        uint256 charge,
        IRelayHub.RelayCallStatus status,
        bytes memory returnValue)
    {
        RelayCallData memory vars;
        vars.initialGasLeft = aggregateGasleft();
        vars.relayRequestId = GsnUtils.getRelayRequestID(relayRequest, signature);

        require(!isDeprecated(), "hub deprecated");
        vars.functionSelector = relayRequest.request.data.length>=4 ? MinLibBytes.readBytes4(relayRequest.request.data, 0) : bytes4(0);

        if (msg.sender != batchGateway && tx.origin != DRY_RUN_ADDRESS) {
            require(signature.length != 0, "missing signature or bad gateway");
            require(msg.sender == tx.origin, "relay worker must be EOA");
            require(msg.sender == relayRequest.relayData.relayWorker, "Not a right worker");
        }

        if (tx.origin != DRY_RUN_ADDRESS) {
            vars.relayManager = workerToManager[relayRequest.relayData.relayWorker];
            require(vars.relayManager != address(0), "Unknown relay worker");
            verifyRelayManagerStaked(vars.relayManager);
        }

        (vars.gasAndDataLimits, vars.maxPossibleGas) =
            verifyGasAndDataLimits(maxAcceptanceBudget, relayRequest, vars.initialGasLeft);

        RelayHubValidator.verifyTransactionPacking(relayRequest,signature,approvalData);

    {

        //How much gas to pass down to innerRelayCall. must be lower than the default 63/64
        // actually, min(gasleft*63/64, gasleft-GAS_RESERVE) might be enough.
        vars.innerGasLimit = gasleft()*63/64- config.gasReserve;
        vars.gasBeforeInner = aggregateGasleft();

        /*
        Preparing to calculate "gasUseWithoutPost":
        MPG = calldataGasUsage + vars.initialGasLeft :: max possible gas, an approximate gas limit for the current transaction
        GU1 = MPG - gasleft(called right before innerRelayCall) :: gas actually used by current transaction until that point
        GU2 = innerGasLimit - gasleft(called inside the innerRelayCall just before preRelayedCall) :: gas actually used by innerRelayCall before calling postRelayCall
        GWP1 = GU1 + GU2 :: gas actually used by the entire transaction before calling postRelayCall
        TGO = config.gasOverhead + config.postOverhead :: extra that will be added to the charge to cover hidden costs
        GWP = GWP1 + TGO :: transaction "gas used without postRelayCall"
        */
        uint256 _tmpInitialGas = relayRequest.relayData.transactionCalldataGasUsed + vars.initialGasLeft + vars.innerGasLimit + config.gasOverhead + config.postOverhead;
        // Calls to the recipient are performed atomically inside an inner transaction which may revert in case of
        // errors in the recipient. In either case (revert or regular execution) the return data encodes the
        // RelayCallStatus value.
        (bool success, bytes memory relayCallStatus) = address(this).call{gas:vars.innerGasLimit}(
            abi.encodeWithSelector(RelayHub.innerRelayCall.selector, relayRequest, signature, approvalData, vars.gasAndDataLimits,
            _tmpInitialGas - aggregateGasleft(), /* totalInitialGas */
            vars.maxPossibleGas
            )
        );
        vars.success = success;
        vars.innerGasUsed = vars.gasBeforeInner-aggregateGasleft();
        (vars.status, vars.relayedCallReturnValue) = abi.decode(relayCallStatus, (RelayCallStatus, bytes));
        if ( vars.relayedCallReturnValue.length>0 ) {
            emit TransactionResult(vars.status, vars.relayedCallReturnValue);
        }
    }
    {
        if (!vars.success) {
            //Failure cases where the PM doesn't pay
            if (vars.status == RelayCallStatus.RejectedByPreRelayed ||
                    (vars.innerGasUsed <= vars.gasAndDataLimits.acceptanceBudget + relayRequest.relayData.transactionCalldataGasUsed) && (
                    vars.status == RelayCallStatus.RejectedByForwarder ||
                    vars.status == RelayCallStatus.RejectedByRecipientRevert  //can only be thrown if rejectOnRecipientRevert==true
                )) {
                emit TransactionRejectedByPaymaster(
                    vars.relayManager,
                    relayRequest.relayData.paymaster,
                    vars.relayRequestId,
                    relayRequest.request.from,
                    relayRequest.request.to,
                    msg.sender,
                    vars.functionSelector,
                    vars.innerGasUsed,
                    vars.relayedCallReturnValue);
                return (false, 0, vars.status, vars.relayedCallReturnValue);
            }
        }

        // We now perform the actual charge calculation, based on the measured gas used
        vars.gasUsed = relayRequest.relayData.transactionCalldataGasUsed + (vars.initialGasLeft - aggregateGasleft()) + config.gasOverhead;
        charge = calculateCharge(vars.gasUsed, relayRequest.relayData);
        vars.devCharge = calculateDevCharge(charge);

        balances[relayRequest.relayData.paymaster] = balances[relayRequest.relayData.paymaster] - charge;
        balances[vars.relayManager] = balances[vars.relayManager] + (charge - vars.devCharge);
        if (vars.devCharge > 0) { // save some gas in case of zero dev charge
            balances[config.devAddress] = balances[config.devAddress] + vars.devCharge;
        }

        {
            address from = relayRequest.request.from;
            address to = relayRequest.request.to;
            address paymaster = relayRequest.relayData.paymaster;
            emit TransactionRelayed(
                vars.relayManager,
                msg.sender,
                vars.relayRequestId,
                from,
                to,
                paymaster,
                vars.functionSelector,
                vars.status,
                charge);
        }

        // avoid variable size memory copying after gas calculation completed on-chain
        if (tx.origin == DRY_RUN_ADDRESS) {
            return (true, charge, vars.status, vars.relayedCallReturnValue);
        }
        return (true, charge, vars.status, "");
    }
    }

    struct InnerRelayCallData {
        uint256 initialGasLeft;
        uint256 gasUsedToCallInner;
        uint256 balanceBefore;
        bytes32 preReturnValue;
        bool relayedCallSuccess;
        bytes relayedCallReturnValue;
        bytes recipientContext;
        bytes data;
        bool rejectOnRecipientRevert;
    }

    /**
     * @notice This method can only by called by this `RelayHub`.
     * It wraps the execution of the `RelayRequest` in a revertable frame context.
     */
    function innerRelayCall(
        GsnTypes.RelayRequest calldata relayRequest,
        bytes calldata signature,
        bytes calldata approvalData,
        IPaymaster.GasAndDataLimits calldata gasAndDataLimits,
        uint256 totalInitialGas,
        uint256 maxPossibleGas
    )
    external
    returns (RelayCallStatus, bytes memory)
    {
        InnerRelayCallData memory vars;
        vars.initialGasLeft = aggregateGasleft();
        vars.gasUsedToCallInner = totalInitialGas - gasleft();
        // A new gas measurement is performed inside innerRelayCall, since
        // due to EIP150 available gas amounts cannot be directly compared across external calls

        // This external function can only be called by RelayHub itself, creating an internal transaction. Calls to the
        // recipient (preRelayedCall, the relayedCall, and postRelayedCall) are called from inside this transaction.
        require(msg.sender == address(this), "Must be called by RelayHub");

        // If either pre or post reverts, the whole internal transaction will be reverted, reverting all side effects on
        // the recipient. The recipient will still be charged for the used gas by the relay.

        // The paymaster is no allowed to withdraw balance from RelayHub during a relayed transaction. We check pre and
        // post state to ensure this doesn't happen.
        vars.balanceBefore = balances[relayRequest.relayData.paymaster];

        // First preRelayedCall is executed.
        // Note: we open a new block to avoid growing the stack too much.
        vars.data = abi.encodeWithSelector(
            IPaymaster.preRelayedCall.selector,
            relayRequest, signature, approvalData, maxPossibleGas
        );
        {
            bool success;
            bytes memory retData;
            (success, retData) = relayRequest.relayData.paymaster.call{gas:gasAndDataLimits.preRelayedCallGasLimit}(vars.data);
            if (!success) {
                GsnEip712Library.truncateInPlace(retData);
                revertWithStatus(RelayCallStatus.RejectedByPreRelayed, retData);
            }
            (vars.recipientContext, vars.rejectOnRecipientRevert) = abi.decode(retData, (bytes,bool));
        }

        // The actual relayed call is now executed. The sender's address is appended at the end of the transaction data

        {
            bool forwarderSuccess;
            (forwarderSuccess, vars.relayedCallSuccess, vars.relayedCallReturnValue) = GsnEip712Library.execute(relayRequest, signature);
            if ( !forwarderSuccess ) {
                revertWithStatus(RelayCallStatus.RejectedByForwarder, vars.relayedCallReturnValue);
            }

            if (vars.rejectOnRecipientRevert && !vars.relayedCallSuccess) {
                // we trusted the recipient, but it reverted...
                revertWithStatus(RelayCallStatus.RejectedByRecipientRevert, vars.relayedCallReturnValue);
            }
        }
        // Finally, postRelayedCall is executed, with the relayedCall execution's status and a charge estimate
        // We now determine how much the recipient will be charged, to pass this value to postRelayedCall for accurate
        // accounting.
        vars.data = abi.encodeWithSelector(
            IPaymaster.postRelayedCall.selector,
            vars.recipientContext,
            vars.relayedCallSuccess,
            vars.gasUsedToCallInner + (vars.initialGasLeft - aggregateGasleft()), /*gasUseWithoutPost*/
            relayRequest.relayData
        );

        {
        (bool successPost,bytes memory ret) = relayRequest.relayData.paymaster.call{gas:gasAndDataLimits.postRelayedCallGasLimit}(vars.data);

            if (!successPost) {
                revertWithStatus(RelayCallStatus.PostRelayedFailed, ret);
            }
        }

        if (balances[relayRequest.relayData.paymaster] < vars.balanceBefore) {
            revertWithStatus(RelayCallStatus.PaymasterBalanceChanged, "");
        }

        return (vars.relayedCallSuccess ? RelayCallStatus.OK : RelayCallStatus.RelayedCallFailed, vars.relayedCallReturnValue);
    }

    /**
     * @dev Reverts the transaction with return data set to the ABI encoding of the status argument (and revert reason data)
     */
    function revertWithStatus(RelayCallStatus status, bytes memory ret) private pure {
        bytes memory data = abi.encode(status, ret);
        GsnEip712Library.truncateInPlace(data);

        assembly {
            let dataSize := mload(data)
            let dataPtr := add(data, 32)

            revert(dataPtr, dataSize)
        }
    }

    /// @inheritdoc IRelayHub
    function calculateDevCharge(uint256 charge) public override virtual view returns (uint256){
        if (config.devFee == 0){ // save some gas in case of zero dev charge
            return 0;
        }
        unchecked {
        return charge * config.devFee / 100;
        }
    }

    /// @inheritdoc IRelayHub
    function calculateCharge(uint256 gasUsed, GsnTypes.RelayData calldata relayData) public override virtual view returns (uint256) {
        uint256 basefee;
        if (relayData.maxFeePerGas == relayData.maxPriorityFeePerGas) {
            basefee = 0;
        } else {
            basefee = block.basefee;
        }
        uint256 chargeableGasPrice = Math.min(relayData.maxFeePerGas, Math.min(tx.gasprice, basefee + relayData.maxPriorityFeePerGas));
        return config.baseRelayFee + (gasUsed * chargeableGasPrice * (config.pctRelayFee + 100)) / 100;
    }

    /// @inheritdoc IRelayHub
    function verifyRelayManagerStaked(address relayManager) public override view {
        (IStakeManager.StakeInfo memory info, bool isHubAuthorized) = stakeManager.getStakeInfo(relayManager);
        uint256 minimumStake = minimumStakePerToken[info.token];
        require(info.token != IERC20(address(0)), "relay manager not staked");
        require(info.stake >= minimumStake, "stake amount is too small");
        require(minimumStake != 0, "staking this token is forbidden");
        require(info.unstakeDelay >= config.minimumUnstakeDelay, "unstake delay is too small");
        require(info.withdrawTime == 0, "stake has been withdrawn");
        require(isHubAuthorized, "this hub is not authorized by SM");
    }

    /// @inheritdoc IRelayHub
    function deprecateHub(uint256 _deprecationTime) public override onlyOwner {
        require(!isDeprecated(), "Already deprecated");
        deprecationTime = _deprecationTime;
        emit HubDeprecated(deprecationTime);
    }

    /// @inheritdoc IRelayHub
    function isDeprecated() public override view returns (bool) {
        return block.timestamp >= deprecationTime;
    }

    /// @notice Prevents any address other than the `Penalizer` from calling this method.
    modifier penalizerOnly () {
        require(msg.sender == penalizer, "Not penalizer");
        _;
    }

    /// @inheritdoc IRelayHub
    function penalize(address relayWorker, address payable beneficiary) external override penalizerOnly {
        address relayManager = workerToManager[relayWorker];
        // The worker must be controlled by a manager with a locked stake
        require(relayManager != address(0), "Unknown relay worker");
        (IStakeManager.StakeInfo memory stakeInfo,) = stakeManager.getStakeInfo(relayManager);
        require(stakeInfo.stake > 0, "relay manager not staked");
        stakeManager.penalizeRelayManager(relayManager, beneficiary, stakeInfo.stake);
    }

    /// @inheritdoc IRelayHub
    function isRelayEscheatable(address relayManager) public view override returns (bool){
        return stakeManager.isRelayEscheatable(relayManager);
    }

    /// @inheritdoc IRelayHub
    function escheatAbandonedRelayBalance(address relayManager) external override onlyOwner {
        require(stakeManager.isRelayEscheatable(relayManager), "relay server not escheatable yet");
        uint256 balance = balances[relayManager];
        balances[relayManager] = 0;
        balances[config.devAddress] = balances[config.devAddress] + balance;
        emit AbandonedRelayManagerBalanceEscheated(relayManager, balance);
    }

    /// @inheritdoc IRelayHub
    function aggregateGasleft() public override virtual view returns (uint256){
        return gasleft();
    }
}

File 11 of 21 : IForwarder.sol
pragma solidity >=0.7.6;
pragma abicoder v2;

// SPDX-License-Identifier: GPL-3.0-only

import "@openzeppelin/contracts/interfaces/IERC165.sol";

/**
 * @title The Forwarder Interface
 * @notice The contracts implementing this interface take a role of authorization, authentication and replay protection
 * for contracts that choose to trust a `Forwarder`, instead of relying on a mechanism built into the Ethereum protocol.
 *
 * @notice if the `Forwarder` contract decides that an incoming `ForwardRequest` is valid, it must append 20 bytes that
 * represent the caller to the `data` field of the request and send this new data to the target address (the `to` field)
 *
 * :warning: **Warning** :warning: The Forwarder can have a full control over a `Recipient` contract.
 * Any vulnerability in a `Forwarder` implementation can make all of its `Recipient` contracts susceptible!
 * Recipient contracts should only trust forwarders that passed through security audit,
 * otherwise they are susceptible to identity theft.
 */
interface IForwarder is IERC165 {

    /**
     * @notice A representation of a request for a `Forwarder` to send `data` on behalf of a `from` to a target (`to`).
     */
    struct ForwardRequest {
        address from;
        address to;
        uint256 value;
        uint256 gas;
        uint256 nonce;
        bytes data;
        uint256 validUntilTime;
    }

    event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue);

    event RequestTypeRegistered(bytes32 indexed typeHash, string typeStr);

    /**
     * @param from The address of a sender.
     * @return The nonce for this address.
     */
    function getNonce(address from)
    external view
    returns(uint256);

    /**
     * @notice Verify the transaction is valid and can be executed.
     * Implementations must validate the signature and the nonce of the request are correct.
     * Does not revert and returns successfully if the input is valid.
     * Reverts if any validation has failed. For instance, if either signature or nonce are incorrect.
     * Reverts if `domainSeparator` or `requestTypeHash` are not registered as well.
     */
    function verify(
        ForwardRequest calldata forwardRequest,
        bytes32 domainSeparator,
        bytes32 requestTypeHash,
        bytes calldata suffixData,
        bytes calldata signature
    ) external view;

    /**
     * @notice Executes a transaction specified by the `ForwardRequest`.
     * The transaction is first verified and then executed.
     * The success flag and returned bytes array of the `CALL` are returned as-is.
     *
     * This method would revert only in case of a verification error.
     *
     * All the target errors are reported using the returned success flag and returned bytes array.
     *
     * @param forwardRequest All requested transaction parameters.
     * @param domainSeparator The domain used when signing this request.
     * @param requestTypeHash The request type used when signing this request.
     * @param suffixData The ABI-encoded extension data for the current `RequestType` used when signing this request.
     * @param signature The client signature to be validated.
     *
     * @return success The success flag of the underlying `CALL` to the target address.
     * @return ret The byte array returned by the underlying `CALL` to the target address.
     */
    function execute(
        ForwardRequest calldata forwardRequest,
        bytes32 domainSeparator,
        bytes32 requestTypeHash,
        bytes calldata suffixData,
        bytes calldata signature
    )
    external payable
    returns (bool success, bytes memory ret);

    /**
     * @notice Register a new Request typehash.
     *
     * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.
     *
     * @param typeName The name of the request type.
     * @param typeSuffix Any extra data after the generic params. Must contain add at least one param.
     * The generic ForwardRequest type is always registered by the constructor.
     */
    function registerRequestType(string calldata typeName, string calldata typeSuffix) external;

    /**
     * @notice Register a new domain separator.
     *
     * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.
     *
     * @notice The domain separator must have the following fields: `name`, `version`, `chainId`, `verifyingContract`.
     * The `chainId` is the current network's `chainId`, and the `verifyingContract` is this Forwarder's address.
     * This method accepts the domain name and version to create and register the domain separator value.
     * @param name The domain's display name.
     * @param version The domain/protocol version.
     */
    function registerDomainSeparator(string calldata name, string calldata version) external;
}

File 12 of 21 : IERC2771Recipient.sol
pragma solidity >=0.6.0;

// SPDX-License-Identifier: MIT

/**
 * @title The ERC-2771 Recipient Base Abstract Class - Declarations
 *
 * @notice A contract must implement this interface in order to support relayed transaction.
 *
 * @notice It is recommended that your contract inherits from the ERC2771Recipient contract.
 */
abstract contract IERC2771Recipient {

    /**
     * :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder.
     * @param forwarder The address of the Forwarder contract that is being used.
     * @return isTrustedForwarder `true` if the Forwarder is trusted to forward relayed transactions by this Recipient.
     */
    function isTrustedForwarder(address forwarder) public virtual view returns(bool);

    /**
     * @notice Use this method the contract anywhere instead of msg.sender to support relayed transactions.
     * @return sender The real sender of this call.
     * For a call that came through the Forwarder the real sender is extracted from the last 20 bytes of the `msg.data`.
     * Otherwise simply returns `msg.sender`.
     */
    function _msgSender() internal virtual view returns (address);

    /**
     * @notice Use this method in the contract instead of `msg.data` when difference matters (hashing, signature, etc.)
     * @return data The real `msg.data` of this call.
     * For a call that came through the Forwarder, the real sender address was appended as the last 20 bytes
     * of the `msg.data` - so this method will strip those 20 bytes off.
     * Otherwise (if the call was made directly and not through the forwarder) simply returns `msg.data`.
     */
    function _msgData() internal virtual view returns (bytes calldata);
}

File 13 of 21 : IPaymaster.sol
pragma solidity >=0.7.6;
pragma abicoder v2;

// SPDX-License-Identifier: GPL-3.0-only

import "@openzeppelin/contracts/interfaces/IERC165.sol";

import "../utils/GsnTypes.sol";

/**
 * @title The Paymaster Interface
 * @notice Contracts implementing this interface exist to make decision about paying the transaction fee to the relay.
 *
 * @notice There are two callbacks here that are executed by the RelayHub: `preRelayedCall` and `postRelayedCall`.
 *
 * @notice It is recommended that your implementation inherits from the abstract BasePaymaster contract.
*/
interface IPaymaster is IERC165 {
    /**
     * @notice The limits this Paymaster wants to be imposed by the RelayHub on user input. See `getGasAndDataLimits`.
     */
    struct GasAndDataLimits {
        uint256 acceptanceBudget;
        uint256 preRelayedCallGasLimit;
        uint256 postRelayedCallGasLimit;
        uint256 calldataSizeLimit;
    }

    /**
     * @notice Return the Gas Limits for Paymaster's functions and maximum msg.data length values for this Paymaster.
     * This function allows different paymasters to have different properties without changes to the RelayHub.
     * @return limits An instance of the `GasAndDataLimits` struct
     *
     * ##### `acceptanceBudget`
     * If the transactions consumes more than `acceptanceBudget` this Paymaster will be charged for gas no matter what.
     * Transaction that gets rejected after consuming more than `acceptanceBudget` gas is on this Paymaster's expense.
     *
     * Should be set to an amount gas this Paymaster expects to spend deciding whether to accept or reject a request.
     * This includes gas consumed by calculations in the `preRelayedCall`, `Forwarder` and the recipient contract.
     *
     * :warning: **Warning** :warning: As long this value is above `preRelayedCallGasLimit`
     * (see defaults in `BasePaymaster`), the Paymaster is guaranteed it will never pay for rejected transactions.
     * If this value is below `preRelayedCallGasLimit`, it might might make Paymaster open to a "griefing" attack.
     *
     * The relayers should prefer lower `acceptanceBudget`, as it improves their chances of being compensated.
     * From a Relay's point of view, this is the highest gas value a bad Paymaster may cost the relay,
     * since the paymaster will pay anything above that value regardless of whether the transaction succeeds or reverts.
     * Specifying value too high might make the call rejected by relayers (see `maxAcceptanceBudget` in server config).
     *
     * ##### `preRelayedCallGasLimit`
     * The max gas usage of preRelayedCall. Any revert of the `preRelayedCall` is a request rejection by the paymaster.
     * As long as `acceptanceBudget` is above `preRelayedCallGasLimit`, any such revert is not payed by the paymaster.
     *
     * ##### `postRelayedCallGasLimit`
     * The max gas usage of postRelayedCall. The Paymaster is not charged for the maximum, only for actually used gas.
     * Note that an OOG will revert the inner transaction, but the paymaster will be charged for it anyway.
     */
    function getGasAndDataLimits()
    external
    view
    returns (
        GasAndDataLimits memory limits
    );

    /**
     * @notice :warning: **Warning** :warning: using incorrect Forwarder may cause the Paymaster to agreeing to pay for invalid transactions.
     * @return trustedForwarder The address of the `Forwarder` that is trusted by this Paymaster to execute the requests.
     */
    function getTrustedForwarder() external view returns (address trustedForwarder);

    /**
     * @return relayHub The address of the `RelayHub` that is trusted by this Paymaster to execute the requests.
     */
    function getRelayHub() external view returns (address relayHub);

    /**
     * @notice Called by the Relay in view mode and later by the `RelayHub` on-chain to validate that
     * the Paymaster agrees to pay for this call.
     *
     * The request is considered to be rejected by the Paymaster in one of the following conditions:
     *  - `preRelayedCall()` method reverts
     *  - the `Forwarder` reverts because of nonce or signature error
     *  - the `Paymaster` returned `rejectOnRecipientRevert: true` and the recipient contract reverted
     *    (and all that did not consume more than `acceptanceBudget` gas).
     *
     * In any of the above cases, all Paymaster calls and the recipient call are reverted.
     * In any other case the Paymaster will pay for the gas cost of the transaction.
     * Note that even if `postRelayedCall` is reverted the Paymaster will be charged.
     *

     * @param relayRequest - the full relay request structure
     * @param signature - user's EIP712-compatible signature of the `relayRequest`.
     * Note that in most cases the paymaster shouldn't try use it at all. It is always checked
     * by the forwarder immediately after preRelayedCall returns.
     * @param approvalData - extra dapp-specific data (e.g. signature from trusted party)
     * @param maxPossibleGas - based on values returned from `getGasAndDataLimits`
     * the RelayHub will calculate the maximum possible amount of gas the user may be charged for.
     * In order to convert this value to wei, the Paymaster has to call "relayHub.calculateCharge()"
     *
     * @return context
     * A byte array to be passed to postRelayedCall.
     * Can contain any data needed by this Paymaster in any form or be empty if no extra data is needed.
     * @return rejectOnRecipientRevert
     * The flag that allows a Paymaster to "delegate" the rejection to the recipient code.
     * It also means the Paymaster trust the recipient to reject fast: both preRelayedCall,
     * forwarder check and recipient checks must fit into the GasLimits.acceptanceBudget,
     * otherwise the TX is paid by the Paymaster.
     * `true` if the Paymaster wants to reject the TX if the recipient reverts.
     * `false` if the Paymaster wants rejects by the recipient to be completed on chain and paid by the Paymaster.
     */
    function preRelayedCall(
        GsnTypes.RelayRequest calldata relayRequest,
        bytes calldata signature,
        bytes calldata approvalData,
        uint256 maxPossibleGas
    )
    external
    returns (bytes memory context, bool rejectOnRecipientRevert);

    /**
     * @notice This method is called after the actual relayed function call.
     * It may be used to record the transaction (e.g. charge the caller by some contract logic) for this call.
     *
     * Revert in this functions causes a revert of the client's relayed call (and preRelayedCall(), but the Paymaster
     * is still committed to pay the relay for the entire transaction.
     *
     * @param context The call context, as returned by the preRelayedCall
     * @param success `true` if the relayed call succeeded, false if it reverted
     * @param gasUseWithoutPost The actual amount of gas used by the entire transaction, EXCEPT
     *        the gas used by the postRelayedCall itself.
     * @param relayData The relay params of the request. can be used by relayHub.calculateCharge()
     *
     */
    function postRelayedCall(
        bytes calldata context,
        bool success,
        uint256 gasUseWithoutPost,
        GsnTypes.RelayData calldata relayData
    ) external;

    /**
     * @return version The SemVer string of this Paymaster's version.
     */
    function versionPaymaster() external view returns (string memory);
}

File 14 of 21 : IRelayHub.sol
pragma solidity >=0.7.6;
pragma abicoder v2;

// SPDX-License-Identifier: GPL-3.0-only

import "@openzeppelin/contracts/interfaces/IERC165.sol";

import "../utils/GsnTypes.sol";
import "./IStakeManager.sol";

/**
 * @title The RelayHub interface
 * @notice The implementation of this interface provides all the information the GSN client needs to
 * create a valid `RelayRequest` and also serves as an entry point for such requests.
 *
 * @notice The RelayHub also handles all the related financial records and hold the balances of participants.
 * The Paymasters keep their Ether deposited in the `RelayHub` in order to pay for the `RelayRequest`s that thay choose
 * to pay for, and Relay Servers keep their earned Ether in the `RelayHub` until they choose to `withdraw()`
 *
 * @notice The RelayHub on each supported network only needs a single instance and there is usually no need for dApp
 * developers or Relay Server operators to redeploy, reimplement, modify or override the `RelayHub`.
 */
interface IRelayHub is IERC165 {
    /**
     * @notice A struct that contains all the parameters of the `RelayHub` that can be modified after the deployment.
     */
    struct RelayHubConfig {
        // maximum number of worker accounts allowed per manager
        uint256 maxWorkerCount;
        // Gas set aside for all relayCall() instructions to prevent unexpected out-of-gas exceptions
        uint256 gasReserve;
        // Gas overhead to calculate gasUseWithoutPost
        uint256 postOverhead;
        // Gas cost of all relayCall() instructions after actual 'calculateCharge()'
        // Assume that relay has non-zero balance (costs 15'000 more otherwise).
        uint256 gasOverhead;
        // Minimum unstake delay seconds of a relay manager's stake on the StakeManager
        uint256 minimumUnstakeDelay;
        // Developers address
        address devAddress;
        // 0 < fee < 100, as percentage of total charge from paymaster to relayer
        uint8 devFee;
        // baseRelayFee The base fee the Relay Server charges for a single transaction in Ether, in wei.
        uint80 baseRelayFee;
        // pctRelayFee The percent of the total charge to add as a Relay Server fee to the total charge.
        uint16 pctRelayFee;
    }

    /// @notice Emitted when a configuration of the `RelayHub` is changed
    event RelayHubConfigured(RelayHubConfig config);

    /// @notice Emitted when relays are added by a relayManager
    event RelayWorkersAdded(
        address indexed relayManager,
        address[] newRelayWorkers,
        uint256 workersCount
    );

    /// @notice Emitted when an account withdraws funds from the `RelayHub`.
    event Withdrawn(
        address indexed account,
        address indexed dest,
        uint256 amount
    );

    /// @notice Emitted when `depositFor` is called, including the amount and account that was funded.
    event Deposited(
        address indexed paymaster,
        address indexed from,
        uint256 amount
    );

    /// @notice Emitted for each token configured for staking in setMinimumStakes
    event StakingTokenDataChanged(
        address token,
        uint256 minimumStake
    );

    /**
     * @notice Emitted when an attempt to relay a call fails and the `Paymaster` does not accept the transaction.
     * The actual relayed call was not executed, and the recipient not charged.
     * @param reason contains a revert reason returned from preRelayedCall or forwarder.
     */
    event TransactionRejectedByPaymaster(
        address indexed relayManager,
        address indexed paymaster,
        bytes32 indexed relayRequestID,
        address from,
        address to,
        address relayWorker,
        bytes4 selector,
        uint256 innerGasUsed,
        bytes reason
    );

    /**
     * @notice Emitted when a transaction is relayed. Note that the actual internal function call might be reverted.
     * The reason for a revert will be indicated in the `status` field of a corresponding `RelayCallStatus` value.
     * @notice `charge` is the Ether value deducted from the `Paymaster` balance.
     * The amount added to the `relayManager` balance will be lower if there is an activated `devFee` in the `config`.
     */
    event TransactionRelayed(
        address indexed relayManager,
        address indexed relayWorker,
        bytes32 indexed relayRequestID,
        address from,
        address to,
        address paymaster,
        bytes4 selector,
        RelayCallStatus status,
        uint256 charge
    );

    /// @notice This event is emitted in case the internal function returns a value or reverts with a revert string.
    event TransactionResult(
        RelayCallStatus status,
        bytes returnValue
    );

    /// @notice This event is emitted in case this `RelayHub` is deprecated and will stop serving transactions soon.
    event HubDeprecated(uint256 deprecationTime);

    /**
     * @notice This event is emitted in case a `relayManager` has been deemed "abandoned" for being
     * unresponsive for a prolonged period of time.
     * @notice This event means the entire balance of the relay has been transferred to the `devAddress`.
     */
    event AbandonedRelayManagerBalanceEscheated(
        address indexed relayManager,
        uint256 balance
    );

    /**
     * Error codes that describe all possible failure reasons reported in the `TransactionRelayed` event `status` field.
     *  @param OK The transaction was successfully relayed and execution successful - never included in the event.
     *  @param RelayedCallFailed The transaction was relayed, but the relayed call failed.
     *  @param RejectedByPreRelayed The transaction was not relayed due to preRelatedCall reverting.
     *  @param RejectedByForwarder The transaction was not relayed due to forwarder check (signature,nonce).
     *  @param PostRelayedFailed The transaction was relayed and reverted due to postRelatedCall reverting.
     *  @param PaymasterBalanceChanged The transaction was relayed and reverted due to the paymaster balance change.
     */
    enum RelayCallStatus {
        OK,
        RelayedCallFailed,
        RejectedByPreRelayed,
        RejectedByForwarder,
        RejectedByRecipientRevert,
        PostRelayedFailed,
        PaymasterBalanceChanged
    }

    /**
     * @notice Add new worker addresses controlled by the sender who must be a staked Relay Manager address.
     * Emits a `RelayWorkersAdded` event.
     * This function can be called multiple times, emitting new events.
     */
    function addRelayWorkers(address[] calldata newRelayWorkers) external;

    /**
     * @notice The `RelayRegistrar` callback to notify the `RelayHub` that this `relayManager` has updated registration.
     */
    function onRelayServerRegistered(address relayManager) external;

    // Balance management

    /**
     * @notice Deposits ether for a `Paymaster`, so that it can and pay for relayed transactions.
     * :warning: **Warning** :warning: Unused balance can only be withdrawn by the holder itself, by calling `withdraw`.
     * Emits a `Deposited` event.
     */
    function depositFor(address target) external payable;

    /**
     * @notice Withdraws from an account's balance, sending it back to the caller.
     * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.
     * Emits a `Withdrawn` event.
     */
    function withdraw(address payable dest, uint256 amount) external;

    /**
     * @notice Withdraws from an account's balance, sending funds to multiple provided addresses.
     * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.
     * Emits a `Withdrawn` event for each destination.
     */
    function withdrawMultiple(address payable[] memory dest, uint256[] memory amount) external;

    // Relaying

    /**
     * @notice Relays a transaction. For this to succeed, multiple conditions must be met:
     *  - `Paymaster`'s `preRelayCall` method must succeed and not revert.
     *  - the `msg.sender` must be a registered Relay Worker that the user signed to use.
     *  - the transaction's gas fees must be equal or larger than the ones that were signed by the sender.
     *  - the transaction must have enough gas to run all internal transactions if they use all gas available to them.
     *  - the `Paymaster` must have enough balance to pay the Relay Worker if all gas is spent.
     *
     * @notice If all conditions are met, the call will be relayed and the `Paymaster` charged.
     *
     * @param maxAcceptanceBudget The maximum valid value for `paymaster.getGasLimits().acceptanceBudget` to return.
     * @param relayRequest All details of the requested relayed call.
     * @param signature The client's EIP-712 signature over the `relayRequest` struct.
     * @param approvalData The dapp-specific data forwarded to the `Paymaster`'s `preRelayedCall` method.
     * This value is **not** verified by the `RelayHub` in any way.
     * As an example, it can be used to pass some kind of a third-party signature to the `Paymaster` for verification.
     *
     * Emits a `TransactionRelayed` event regardless of whether the transaction succeeded or failed.
     */
    function relayCall(
        uint256 maxAcceptanceBudget,
        GsnTypes.RelayRequest calldata relayRequest,
        bytes calldata signature,
        bytes calldata approvalData
    )
    external
    returns (
        bool paymasterAccepted,
        uint256 charge,
        IRelayHub.RelayCallStatus status,
        bytes memory returnValue
    );

    /**
     * @notice In case the Relay Worker has been found to be in violation of some rules by the `Penalizer` contract,
     * the `Penalizer` will call this method to execute a penalization.
     * The `RelayHub` will look up the Relay Manager of the given Relay Worker and will forward the call to
     * the `StakeManager` contract. The `RelayHub` does not perform the actual penalization either.
     * @param relayWorker The address of the Relay Worker that committed a penalizable offense.
     * @param beneficiary The address that called the `Penalizer` and will receive a reward for it.
     */
    function penalize(address relayWorker, address payable beneficiary) external;

    /**
     * @notice Sets or changes the configuration of this `RelayHub`.
     * @param _config The new configuration.
     */
    function setConfiguration(RelayHubConfig memory _config) external;

    /**
     * @notice Sets or changes the minimum amount of a given `token` that needs to be staked so that the Relay Manager
     * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.
     * @param token An array of addresses of ERC-20 compatible tokens.
     * @param minimumStake An array of minimal amounts necessary for a corresponding token, in wei.
     */
    function setMinimumStakes(IERC20[] memory token, uint256[] memory minimumStake) external;

    /**
     * @notice Deprecate hub by reverting all incoming `relayCall()` calls starting from a given timestamp
     * @param _deprecationTime The timestamp in seconds after which the `RelayHub` stops serving transactions.
     */
    function deprecateHub(uint256 _deprecationTime) external;

    /**
     * @notice
     * @param relayManager
     */
    function escheatAbandonedRelayBalance(address relayManager) external;

    /**
     * @notice The fee is expressed as a base fee in wei plus percentage of the actual charge.
     * For example, a value '40' stands for a 40% fee, so the recipient will be charged for 1.4 times the spent amount.
     * @param gasUsed An amount of gas used by the transaction.
     * @param relayData The details of a transaction signed by the sender.
     * @return The calculated charge, in wei.
     */
    function calculateCharge(uint256 gasUsed, GsnTypes.RelayData calldata relayData) external view returns (uint256);

    /**
     * @notice The fee is expressed as a  percentage of the actual charge.
     * For example, a value '40' stands for a 40% fee, so the Relay Manager will only get 60% of the `charge`.
     * @param charge The amount of Ether in wei the Paymaster will be charged for this transaction.
     * @return The calculated devFee, in wei.
     */
    function calculateDevCharge(uint256 charge) external view returns (uint256);
    /* getters */

    /// @return config The configuration of the `RelayHub`.
    function getConfiguration() external view returns (RelayHubConfig memory config);

    /**
     * @param token An address of an ERC-20 compatible tokens.
     * @return The minimum amount of a given `token` that needs to be staked so that the Relay Manager
     * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.
     */
    function getMinimumStakePerToken(IERC20 token) external view returns (uint256);

    /**
     * @param worker An address of the Relay Worker.
     * @return The address of its Relay Manager.
     */
    function getWorkerManager(address worker) external view returns (address);

    /**
     * @param manager An address of the Relay Manager.
     * @return The count of Relay Workers associated with this Relay Manager.
     */
    function getWorkerCount(address manager) external view returns (uint256);

    /// @return An account's balance. It can be either a deposit of a `Paymaster`, or a revenue of a Relay Manager.
    function balanceOf(address target) external view returns (uint256);

    /// @return The `StakeManager` address for this `RelayHub`.
    function getStakeManager() external view returns (IStakeManager);

    /// @return The `Penalizer` address for this `RelayHub`.
    function getPenalizer() external view returns (address);

    /// @return The `RelayRegistrar` address for this `RelayHub`.
    function getRelayRegistrar() external view returns (address);

    /// @return The `BatchGateway` address for this `RelayHub`.
    function getBatchGateway() external view returns (address);

    /**
     * @notice Uses `StakeManager` to decide if the Relay Manager can be considered staked or not.
     * Returns if the stake's token, amount and delay satisfy all requirements, reverts otherwise.
     */
    function verifyRelayManagerStaked(address relayManager) external view;

    /**
     * @notice Uses `StakeManager` to check if the Relay Manager can be considered abandoned or not.
     * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.
     */
    function isRelayEscheatable(address relayManager) external view returns (bool);

    /// @return `true` if the `RelayHub` is deprecated, `false` it it is not deprecated and can serve transactions.
    function isDeprecated() external view returns (bool);

    /// @return The timestamp from which the hub no longer allows relaying calls.
    function getDeprecationTime() external view returns (uint256);

    /// @return The block number in which the contract has been deployed.
    function getCreationBlock() external view returns (uint256);

    /// @return a SemVer-compliant version of the `RelayHub` contract.
    function versionHub() external view returns (string memory);

    /// @return A total measurable amount of gas left to current execution. Same as 'gasleft()' for pure EVMs.
    function aggregateGasleft() external view returns (uint256);
}

File 15 of 21 : IRelayRegistrar.sol
pragma solidity ^0.8.6;

//SPDX-License-Identifier: GPL-3.0-only

import "@openzeppelin/contracts/interfaces/IERC165.sol";

/**
 * @title The RelayRegistrar Interface
 * @notice The on-chain registrar for all registered Relay Managers.
 *
 * @notice The client can use an implementation of a `RelayRegistrar` to find relay registration info.
 *
 */
interface IRelayRegistrar is IERC165 {

    /**
     * @notice A struct containing all the information necessary to client to interact with the Relay Server.
     */
    struct RelayInfo {
        //last registration block number
        uint32 lastSeenBlockNumber;
        //last registration block timestamp
        uint40 lastSeenTimestamp;
        //stake (first registration) block number
        uint32 firstSeenBlockNumber;
        //stake (first registration) block timestamp
        uint40 firstSeenTimestamp;
        bytes32[3] urlParts;
        address relayManager;
    }

    /**
     * @notice Emitted when a relay server registers or updates its details.
     * Looking up these events allows a client to discover registered Relay Servers.
     */
    event RelayServerRegistered(
        address indexed relayManager,
        address indexed relayHub,
        bytes32[3] relayUrl
    );

    /**
     * @notice This function is called by Relay Servers in order to register or to update their registration.
     * @param relayHub The address of the `RelayHub` contract for which this action is performed.
     * @param url The URL of the Relay Server that is listening to the clients' requests.
     */
    function registerRelayServer(
        address relayHub,
        bytes32[3] calldata url
    ) external;

    /**
     * @return The block number in which the contract has been deployed.
     */
    function getCreationBlock() external view returns (uint256);

    /**
     * @return The maximum age the relay is considered registered by default by this `RelayRegistrar`, in seconds.
     */
    function getRelayRegistrationMaxAge() external view returns (uint256);

    /**
     * @notice Change the maximum relay registration age.
     */
    function setRelayRegistrationMaxAge(uint256) external;

    /**
     * @param relayManager An address of a Relay Manager.
     * @param relayHub The address of the `RelayHub` contract for which this action is performed.
     * @return info All the details of the given Relay Manager's registration. Throws if relay not found for `RelayHub`.
     */
    function getRelayInfo(address relayHub, address relayManager) external view returns (RelayInfo memory info);

    /**
     * @notice Read relay info of registered Relay Server from an on-chain storage.
     * @param relayHub The address of the `RelayHub` contract for which this action is performed.
     * @return info The list of `RelayInfo`s of registered Relay Servers
     */
    function readRelayInfos(
        address relayHub
    ) external view returns (
        RelayInfo[] memory info
    );

    /**
     * @notice Read relay info of registered Relay Server from an on-chain storage.
     * @param relayHub The address of the `RelayHub` contract for which this action is performed.
     * @param maxCount The maximum amount of relays to be returned by this function.
     * @param oldestBlockNumber The latest block number in which a Relay Server may be registered.
     * @param oldestBlockTimestamp The latest block timestamp in which a Relay Server may be registered.
     * @return info The list of `RelayInfo`s of registered Relay Servers
     */
    function readRelayInfosInRange(
        address relayHub,
        uint256 oldestBlockNumber,
        uint256 oldestBlockTimestamp,
        uint256 maxCount
    ) external view returns (
        RelayInfo[] memory info
    );
}

File 16 of 21 : IStakeManager.sol
pragma solidity >=0.7.6;
pragma abicoder v2;

// SPDX-License-Identifier: GPL-3.0-only

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

/**
 * @title The StakeManager Interface
 * @notice In order to prevent an attacker from registering a large number of unresponsive relays, the GSN requires
 * the Relay Server to maintain a permanently locked stake in the system before being able to register.
 *
 * @notice Also, in some cases the behavior of a Relay Server may be found to be illegal by a `Penalizer` contract.
 * In such case, the stake will never be returned to the Relay Server operator and will be slashed.
 *
 * @notice An implementation of this interface is tasked with keeping Relay Servers' stakes, made in any ERC-20 token.
 * Note that the `RelayHub` chooses which ERC-20 tokens to support and how much stake is needed.
 */
interface IStakeManager is IERC165 {

    /// @notice Emitted when a `stake` or `unstakeDelay` are initialized or increased.
    event StakeAdded(
        address indexed relayManager,
        address indexed owner,
        IERC20 token,
        uint256 stake,
        uint256 unstakeDelay
    );

    /// @notice Emitted once a stake is scheduled for withdrawal.
    event StakeUnlocked(
        address indexed relayManager,
        address indexed owner,
        uint256 withdrawTime
    );

    /// @notice Emitted when owner withdraws `relayManager` funds.
    event StakeWithdrawn(
        address indexed relayManager,
        address indexed owner,
        IERC20 token,
        uint256 amount
    );

    /// @notice Emitted when an authorized `RelayHub` penalizes a `relayManager`.
    event StakePenalized(
        address indexed relayManager,
        address indexed beneficiary,
        IERC20 token,
        uint256 reward
    );

    /// @notice Emitted when a `relayManager` adds a new `RelayHub` to a list of authorized.
    event HubAuthorized(
        address indexed relayManager,
        address indexed relayHub
    );

    /// @notice Emitted when a `relayManager` removes a `RelayHub` from a list of authorized.
    event HubUnauthorized(
        address indexed relayManager,
        address indexed relayHub,
        uint256 removalTime
    );

    /// @notice Emitted when a `relayManager` sets its `owner`. This is necessary to prevent stake hijacking.
    event OwnerSet(
        address indexed relayManager,
        address indexed owner
    );

    /// @notice Emitted when a `burnAddress` is changed.
    event BurnAddressSet(
        address indexed burnAddress
    );

    /// @notice Emitted when a `devAddress` is changed.
    event DevAddressSet(
        address indexed devAddress
    );

    /// @notice Emitted if Relay Server is inactive for an `abandonmentDelay` and contract owner initiates its removal.
    event RelayServerAbandoned(
        address indexed relayManager,
        uint256 abandonedTime
    );

    /// @notice Emitted to indicate an action performed by a relay server to prevent it from being marked as abandoned.
    event RelayServerKeepalive(
        address indexed relayManager,
        uint256 keepaliveTime
    );

    /// @notice Emitted when the stake of an abandoned relayer has been confiscated and transferred to the `devAddress`.
    event AbandonedRelayManagerStakeEscheated(
        address indexed relayManager,
        address indexed owner,
        IERC20 token,
        uint256 amount
    );

    /**
     * @param stake - amount of ether staked for this relay
     * @param unstakeDelay - number of seconds to elapse before the owner can retrieve the stake after calling 'unlock'
     * @param withdrawTime - timestamp in seconds when 'withdraw' will be callable, or zero if the unlock has not been called
     * @param owner - address that receives revenue and manages relayManager's stake
     */
    struct StakeInfo {
        uint256 stake;
        uint256 unstakeDelay;
        uint256 withdrawTime;
        uint256 abandonedTime;
        uint256 keepaliveTime;
        IERC20 token;
        address owner;
    }

    struct RelayHubInfo {
        uint256 removalTime;
    }

    /**
     * @param devAddress - the address that will receive the 'abandoned' stake
     * @param abandonmentDelay - the amount of time after which the relay can be marked as 'abandoned'
     * @param escheatmentDelay - the amount of time after which the abandoned relay's stake and balance may be withdrawn to the `devAddress`
     */
    struct AbandonedRelayServerConfig {
        address devAddress;
        uint256 abandonmentDelay;
        uint256 escheatmentDelay;
    }

    /**
     * @notice Set the owner of a Relay Manager. Called only by the RelayManager itself.
     * Note that owners cannot transfer ownership - if the entry already exists, reverts.
     * @param owner - owner of the relay (as configured off-chain)
     */
    function setRelayManagerOwner(address owner) external;

    /**
     * @notice Put a stake for a relayManager and set its unstake delay.
     * Only the owner can call this function. If the entry does not exist, reverts.
     * The owner must give allowance of the ERC-20 token to the StakeManager before calling this method.
     * It is the RelayHub who has a configurable list of minimum stakes per token. StakeManager accepts all tokens.
     * @param token The address of an ERC-20 token that is used by the relayManager as a stake
     * @param relayManager The address that represents a stake entry and controls relay registrations on relay hubs
     * @param unstakeDelay The number of seconds to elapse before an owner can retrieve the stake after calling `unlock`
     * @param amount The amount of tokens to be taken from the relayOwner and locked in the StakeManager as a stake
     */
    function stakeForRelayManager(IERC20 token, address relayManager, uint256 unstakeDelay, uint256 amount) external;

    /**
     * @notice Schedule the unlocking of the stake. The `unstakeDelay` must pass before owner can call `withdrawStake`.
     * @param relayManager The address of a Relay Manager whose stake is to be unlocked.
     */
    function unlockStake(address relayManager) external;
    /**
     * @notice Withdraw the unlocked stake.
     * @param relayManager The address of a Relay Manager whose stake is to be withdrawn.
     */
    function withdrawStake(address relayManager) external;

    /**
     * @notice Add the `RelayHub` to a list of authorized by this Relay Manager.
     * This allows the RelayHub to penalize this Relay Manager. The `RelayHub` cannot trust a Relay it cannot penalize.
     * @param relayManager The address of a Relay Manager whose stake is to be authorized for the new `RelayHub`.
     * @param relayHub The address of a `RelayHub` to be authorized.
     */
    function authorizeHubByOwner(address relayManager, address relayHub) external;

    /**
     * @notice Same as `authorizeHubByOwner` but can be called by the RelayManager itself.
     */
    function authorizeHubByManager(address relayHub) external;

    /**
     * @notice Remove the `RelayHub` from a list of authorized by this Relay Manager.
     * @param relayManager The address of a Relay Manager.
     * @param relayHub The address of a `RelayHub` to be unauthorized.
     */
    function unauthorizeHubByOwner(address relayManager, address relayHub) external;

    /**
     * @notice Same as `unauthorizeHubByOwner` but can be called by the RelayManager itself.
     */
    function unauthorizeHubByManager(address relayHub) external;

    /**
     * Slash the stake of the relay relayManager. In order to prevent stake kidnapping, burns part of stake on the way.
     * @param relayManager The address of a Relay Manager to be penalized.
     * @param beneficiary The address that receives part of the penalty amount.
     * @param amount A total amount of penalty to be withdrawn from stake.
     */
    function penalizeRelayManager(address relayManager, address beneficiary, uint256 amount) external;

    /**
     * @notice Allows the contract owner to set the given `relayManager` as abandoned after a configurable delay.
     * Its entire stake and balance will be taken from a relay if it does not respond to being marked as abandoned.
     */
    function markRelayAbandoned(address relayManager) external;

    /**
     * @notice If more than `abandonmentDelay` has passed since the last Keepalive transaction, and relay manager
     * has been marked as abandoned, and after that more that `escheatmentDelay` have passed, entire stake and
     * balance will be taken from this relay.
     */
    function escheatAbandonedRelayStake(address relayManager) external;

    /**
     * @notice Sets a new `keepaliveTime` for the given `relayManager`, preventing it from being marked as abandoned.
     * Can be called by an authorized `RelayHub` or by the `relayOwner` address.
     */
    function updateRelayKeepaliveTime(address relayManager) external;

    /**
     * @notice Check if the Relay Manager can be considered abandoned or not.
     * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.
     */
    function isRelayEscheatable(address relayManager) external view returns(bool);

    /**
     * @notice Get the stake details information for the given Relay Manager.
     * @param relayManager The address of a Relay Manager.
     * @return stakeInfo The `StakeInfo` structure.
     * @return isSenderAuthorizedHub `true` if the `msg.sender` for this call was a `RelayHub` that is authorized now.
     * `false` if the `msg.sender` for this call is not authorized.
     */
    function getStakeInfo(address relayManager) external view returns (StakeInfo memory stakeInfo, bool isSenderAuthorizedHub);

    /**
     * @return The maximum unstake delay this `StakeManger` allows. This is to prevent locking money forever by mistake.
     */
    function getMaxUnstakeDelay() external view returns (uint256);

    /**
     * @notice Change the address that will receive the 'burned' part of the penalized stake.
     * This is done to prevent malicious Relay Server from penalizing itself and breaking even.
     */
    function setBurnAddress(address _burnAddress) external;

    /**
     * @return The address that will receive the 'burned' part of the penalized stake.
     */
    function getBurnAddress() external view returns (address);

    /**
     * @notice Change the address that will receive the 'abandoned' stake.
     * This is done to prevent Relay Servers that lost their keys from losing access to funds.
     */
    function setDevAddress(address _burnAddress) external;

    /**
     * @return The structure that contains all configuration values for the 'abandoned' stake.
     */
    function getAbandonedRelayServerConfig() external view returns (AbandonedRelayServerConfig memory);

    /**
     * @return the block number in which the contract has been deployed.
     */
    function getCreationBlock() external view returns (uint256);

    /**
     * @return a SemVer-compliant version of the `StakeManager` contract.
     */
    function versionSM() external view returns (string memory);
}

File 17 of 21 : GsnEip712Library.sol
pragma solidity ^0.8.0;
pragma abicoder v2;

// SPDX-License-Identifier: GPL-3.0-only

import "../utils/GsnTypes.sol";
import "../interfaces/IERC2771Recipient.sol";
import "../forwarder/IForwarder.sol";

import "./GsnUtils.sol";

/**
 * @title The ERC-712 Library for GSN
 * @notice Bridge Library to convert a GSN RelayRequest into a valid `ForwardRequest` for a `Forwarder`.
 */
library GsnEip712Library {
    // maximum length of return value/revert reason for 'execute' method. Will truncate result if exceeded.
    uint256 private constant MAX_RETURN_SIZE = 1024;

    //copied from Forwarder (can't reference string constants even from another library)
    string public constant GENERIC_PARAMS = "address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data,uint256 validUntilTime";

    bytes public constant RELAYDATA_TYPE = "RelayData(uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,uint256 transactionCalldataGasUsed,address relayWorker,address paymaster,address forwarder,bytes paymasterData,uint256 clientId)";

    string public constant RELAY_REQUEST_NAME = "RelayRequest";
    string public constant RELAY_REQUEST_SUFFIX = string(abi.encodePacked("RelayData relayData)", RELAYDATA_TYPE));

    bytes public constant RELAY_REQUEST_TYPE = abi.encodePacked(
        RELAY_REQUEST_NAME,"(",GENERIC_PARAMS,",", RELAY_REQUEST_SUFFIX);

    bytes32 public constant RELAYDATA_TYPEHASH = keccak256(RELAYDATA_TYPE);
    bytes32 public constant RELAY_REQUEST_TYPEHASH = keccak256(RELAY_REQUEST_TYPE);

    struct EIP712Domain {
        string name;
        string version;
        uint256 chainId;
        address verifyingContract;
    }

    bytes32 public constant EIP712DOMAIN_TYPEHASH = keccak256(
        "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
    );

    function splitRequest(
        GsnTypes.RelayRequest calldata req
    )
    internal
    pure
    returns (
        bytes memory suffixData
    ) {
        suffixData = abi.encode(
            hashRelayData(req.relayData));
    }

    //verify that the recipient trusts the given forwarder
    // MUST be called by paymaster
    function verifyForwarderTrusted(GsnTypes.RelayRequest calldata relayRequest) internal view {
        (bool success, bytes memory ret) = relayRequest.request.to.staticcall(
            abi.encodeWithSelector(
                IERC2771Recipient.isTrustedForwarder.selector, relayRequest.relayData.forwarder
            )
        );
        require(success, "isTrustedForwarder: reverted");
        require(ret.length == 32, "isTrustedForwarder: bad response");
        require(abi.decode(ret, (bool)), "invalid forwarder for recipient");
    }

    function verifySignature(GsnTypes.RelayRequest calldata relayRequest, bytes calldata signature) internal view {
        (bytes memory suffixData) = splitRequest(relayRequest);
        bytes32 _domainSeparator = domainSeparator(relayRequest.relayData.forwarder);
        IForwarder forwarder = IForwarder(payable(relayRequest.relayData.forwarder));
        forwarder.verify(relayRequest.request, _domainSeparator, RELAY_REQUEST_TYPEHASH, suffixData, signature);
    }

    function verify(GsnTypes.RelayRequest calldata relayRequest, bytes calldata signature) internal view {
        verifyForwarderTrusted(relayRequest);
        verifySignature(relayRequest, signature);
    }

    function execute(GsnTypes.RelayRequest calldata relayRequest, bytes calldata signature) internal returns (bool forwarderSuccess, bool callSuccess, bytes memory ret) {
        (bytes memory suffixData) = splitRequest(relayRequest);
        bytes32 _domainSeparator = domainSeparator(relayRequest.relayData.forwarder);
        /* solhint-disable-next-line avoid-low-level-calls */
        (forwarderSuccess, ret) = relayRequest.relayData.forwarder.call(
            abi.encodeWithSelector(IForwarder.execute.selector,
            relayRequest.request, _domainSeparator, RELAY_REQUEST_TYPEHASH, suffixData, signature
        ));
        if ( forwarderSuccess ) {

          //decode return value of execute:
          (callSuccess, ret) = abi.decode(ret, (bool, bytes));
        }
        truncateInPlace(ret);
    }

    //truncate the given parameter (in-place) if its length is above the given maximum length
    // do nothing otherwise.
    //NOTE: solidity warns unless the method is marked "pure", but it DOES modify its parameter.
    function truncateInPlace(bytes memory data) internal pure {
        MinLibBytes.truncateInPlace(data, MAX_RETURN_SIZE);
    }

    function domainSeparator(address forwarder) internal view returns (bytes32) {
        return hashDomain(EIP712Domain({
            name : "GSN Relayed Transaction",
            version : "3",
            chainId : getChainID(),
            verifyingContract : forwarder
            }));
    }

    function getChainID() internal view returns (uint256 id) {
        /* solhint-disable no-inline-assembly */
        assembly {
            id := chainid()
        }
    }

    function hashDomain(EIP712Domain memory req) internal pure returns (bytes32) {
        return keccak256(abi.encode(
                EIP712DOMAIN_TYPEHASH,
                keccak256(bytes(req.name)),
                keccak256(bytes(req.version)),
                req.chainId,
                req.verifyingContract));
    }

    function hashRelayData(GsnTypes.RelayData calldata req) internal pure returns (bytes32) {
        return keccak256(abi.encode(
                RELAYDATA_TYPEHASH,
                req.maxFeePerGas,
                req.maxPriorityFeePerGas,
                req.transactionCalldataGasUsed,
                req.relayWorker,
                req.paymaster,
                req.forwarder,
                keccak256(req.paymasterData),
                req.clientId
            ));
    }
}

File 18 of 21 : GsnTypes.sol
pragma solidity ^0.8.0;

// SPDX-License-Identifier: GPL-3.0-only

import "../forwarder/IForwarder.sol";

interface GsnTypes {
    /// @notice maxFeePerGas, maxPriorityFeePerGas, pctRelayFee and baseRelayFee must be validated inside of the paymaster's preRelayedCall in order not to overpay
    struct RelayData {
        uint256 maxFeePerGas;
        uint256 maxPriorityFeePerGas;
        uint256 transactionCalldataGasUsed;
        address relayWorker;
        address paymaster;
        address forwarder;
        bytes paymasterData;
        uint256 clientId;
    }

    //note: must start with the ForwardRequest to be an extension of the generic forwarder
    struct RelayRequest {
        IForwarder.ForwardRequest request;
        RelayData relayData;
    }
}

File 19 of 21 : GsnUtils.sol
pragma solidity ^0.8.0;

/* solhint-disable no-inline-assembly */
// SPDX-License-Identifier: GPL-3.0-only

import "../utils/MinLibBytes.sol";
import "./GsnTypes.sol";

/**
 * @title The GSN Solidity Utils Library
 * @notice Some library functions used throughout the GSN Solidity codebase.
 */
library GsnUtils {

    bytes32 constant private RELAY_REQUEST_ID_MASK = 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

    /**
     * @notice Calculate an identifier for the meta-transaction in a format similar to a transaction hash.
     * Note that uniqueness relies on signature and may not be enforced if meta-transactions are verified
     * with a different algorithm, e.g. when batching.
     * @param relayRequest The `RelayRequest` for which an ID is being calculated.
     * @param signature The signature for the `RelayRequest`. It is not validated here and may even remain empty.
     */
    function getRelayRequestID(GsnTypes.RelayRequest calldata relayRequest, bytes calldata signature)
    internal
    pure
    returns (bytes32) {
        return keccak256(abi.encode(relayRequest.request.from, relayRequest.request.nonce, signature)) & RELAY_REQUEST_ID_MASK;
    }

    /**
     * @notice Extract the method identifier signature from the encoded function call.
     */
    function getMethodSig(bytes memory msgData) internal pure returns (bytes4) {
        return MinLibBytes.readBytes4(msgData, 0);
    }

    /**
     * @notice Extract a parameter from encoded-function block.
     * see: https://solidity.readthedocs.io/en/develop/abi-spec.html#formal-specification-of-the-encoding
     * The return value should be casted to the right type (`uintXXX`/`bytesXXX`/`address`/`bool`/`enum`).
     * @param msgData Byte array containing a uint256 value.
     * @param index Index in byte array of uint256 value.
     * @return result uint256 value from byte array.
     */
    function getParam(bytes memory msgData, uint256 index) internal pure returns (uint256 result) {
        return MinLibBytes.readUint256(msgData, 4 + index * 32);
    }

    /// @notice Re-throw revert with the same revert data.
    function revertWithData(bytes memory data) internal pure {
        assembly {
            revert(add(data,32), mload(data))
        }
    }

}

File 20 of 21 : MinLibBytes.sol
pragma solidity ^0.8.0;

// SPDX-License-Identifier: MIT
// minimal bytes manipulation required by GSN
// a minimal subset from 0x/LibBytes
/* solhint-disable no-inline-assembly */

library MinLibBytes {

    //truncate the given parameter (in-place) if its length is above the given maximum length
    // do nothing otherwise.
    //NOTE: solidity warns unless the method is marked "pure", but it DOES modify its parameter.
    function truncateInPlace(bytes memory data, uint256 maxlen) internal pure {
        if (data.length > maxlen) {
            assembly { mstore(data, maxlen) }
        }
    }

    /// @dev Reads an address from a position in a byte array.
    /// @param b Byte array containing an address.
    /// @param index Index in byte array of address.
    /// @return result address from byte array.
    function readAddress(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (address result)
    {
        require (b.length >= index + 20, "readAddress: data too short");

        // Add offset to index:
        // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)
        // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)
        index += 20;

        // Read address from array memory
        assembly {
            // 1. Add index to address of bytes array
            // 2. Load 32-byte word from memory
            // 3. Apply 20-byte mask to obtain address
            result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)
        }
        return result;
    }

    function readBytes32(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (bytes32 result)
    {
        require(b.length >= index + 32, "readBytes32: data too short" );

        // Read the bytes32 from array memory
        assembly {
            result := mload(add(b, add(index,32)))
        }
        return result;
    }

    /// @dev Reads a uint256 value from a position in a byte array.
    /// @param b Byte array containing a uint256 value.
    /// @param index Index in byte array of uint256 value.
    /// @return result uint256 value from byte array.
    function readUint256(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (uint256 result)
    {
        result = uint256(readBytes32(b, index));
        return result;
    }

    function readBytes4(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (bytes4 result)
    {
        require(b.length >= index + 4, "readBytes4: data too short");

        // Read the bytes4 from array memory
        assembly {
            result := mload(add(b, add(index,32)))
            // Solidity does not require us to clean the trailing bytes.
            // We do it anyway
            result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
        }
        return result;
    }
}

File 21 of 21 : RelayHubValidator.sol
pragma solidity ^0.8.0;
pragma abicoder v2;

// SPDX-License-Identifier: GPL-3.0-only

import "../utils/GsnTypes.sol";

/**
 * @title The RelayHub Validator Library
 * @notice Validates the `msg.data` received by the `RelayHub` does not contain unnecessary bytes.
 * Including these extra bytes would allow the Relay Server to inflate transaction costs and overcharge the client.
 */
library RelayHubValidator {

    /// @notice Validate that encoded `relayCall` is properly packed without any extra bytes
    function verifyTransactionPacking(
        GsnTypes.RelayRequest calldata relayRequest,
        bytes calldata signature,
        bytes calldata approvalData
    ) internal pure {
        // abicoder v2: https://docs.soliditylang.org/en/latest/abi-spec.html
        // each static param/member is 1 word
        // struct (with dynamic members) has offset to struct which is 1 word
        // dynamic member is 1 word offset to actual value, which is 1-word length and ceil(length/32) words for data
        // relayCall has 5 method params,
        // relayRequest: 2 members
        // relayData 8 members
        // ForwardRequest: 7 members
        // total 21 32-byte words if all dynamic params are zero-length.
        uint256 expectedMsgDataLen = 4 + 21 * 32 +
            dynamicParamSize(signature) +
            dynamicParamSize(approvalData) +
            dynamicParamSize(relayRequest.request.data) +
            dynamicParamSize(relayRequest.relayData.paymasterData);
        // zero-length signature is allowed in a batch relay transaction
        require(signature.length <= 65, "invalid signature length");
        require(expectedMsgDataLen == msg.data.length, "extra msg.data bytes" );
    }

    // helper method for verifyTransactionPacking:
    // size (in bytes) of the given "bytes" parameter. size include the length (32-byte word),
    // and actual data size, rounded up to full 32-byte words
    function dynamicParamSize(bytes calldata buf) internal pure returns (uint256) {
        return 32 + ((buf.length + 31) & (type(uint256).max - 31));
    }
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"inputs":[{"internalType":"contract IStakeManager","name":"_stakeManager","type":"address"},{"internalType":"address","name":"_penalizer","type":"address"},{"internalType":"address","name":"_batchGateway","type":"address"},{"internalType":"address","name":"_relayRegistrar","type":"address"},{"components":[{"internalType":"uint256","name":"maxWorkerCount","type":"uint256"},{"internalType":"uint256","name":"gasReserve","type":"uint256"},{"internalType":"uint256","name":"postOverhead","type":"uint256"},{"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"internalType":"uint256","name":"minimumUnstakeDelay","type":"uint256"},{"internalType":"address","name":"devAddress","type":"address"},{"internalType":"uint8","name":"devFee","type":"uint8"},{"internalType":"uint80","name":"baseRelayFee","type":"uint80"},{"internalType":"uint16","name":"pctRelayFee","type":"uint16"}],"internalType":"struct IRelayHub.RelayHubConfig","name":"_config","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"relayManager","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"AbandonedRelayManagerBalanceEscheated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"paymaster","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"deprecationTime","type":"uint256"}],"name":"HubDeprecated","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":[{"components":[{"internalType":"uint256","name":"maxWorkerCount","type":"uint256"},{"internalType":"uint256","name":"gasReserve","type":"uint256"},{"internalType":"uint256","name":"postOverhead","type":"uint256"},{"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"internalType":"uint256","name":"minimumUnstakeDelay","type":"uint256"},{"internalType":"address","name":"devAddress","type":"address"},{"internalType":"uint8","name":"devFee","type":"uint8"},{"internalType":"uint80","name":"baseRelayFee","type":"uint80"},{"internalType":"uint16","name":"pctRelayFee","type":"uint16"}],"indexed":false,"internalType":"struct IRelayHub.RelayHubConfig","name":"config","type":"tuple"}],"name":"RelayHubConfigured","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"relayManager","type":"address"},{"indexed":false,"internalType":"address[]","name":"newRelayWorkers","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"workersCount","type":"uint256"}],"name":"RelayWorkersAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"minimumStake","type":"uint256"}],"name":"StakingTokenDataChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"relayManager","type":"address"},{"indexed":true,"internalType":"address","name":"paymaster","type":"address"},{"indexed":true,"internalType":"bytes32","name":"relayRequestID","type":"bytes32"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"relayWorker","type":"address"},{"indexed":false,"internalType":"bytes4","name":"selector","type":"bytes4"},{"indexed":false,"internalType":"uint256","name":"innerGasUsed","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TransactionRejectedByPaymaster","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"relayManager","type":"address"},{"indexed":true,"internalType":"address","name":"relayWorker","type":"address"},{"indexed":true,"internalType":"bytes32","name":"relayRequestID","type":"bytes32"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"paymaster","type":"address"},{"indexed":false,"internalType":"bytes4","name":"selector","type":"bytes4"},{"indexed":false,"internalType":"enum IRelayHub.RelayCallStatus","name":"status","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"charge","type":"uint256"}],"name":"TransactionRelayed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum IRelayHub.RelayCallStatus","name":"status","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"returnValue","type":"bytes"}],"name":"TransactionResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"dest","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address[]","name":"newRelayWorkers","type":"address[]"}],"name":"addRelayWorkers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"aggregateGasleft","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"components":[{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"uint256","name":"transactionCalldataGasUsed","type":"uint256"},{"internalType":"address","name":"relayWorker","type":"address"},{"internalType":"address","name":"paymaster","type":"address"},{"internalType":"address","name":"forwarder","type":"address"},{"internalType":"bytes","name":"paymasterData","type":"bytes"},{"internalType":"uint256","name":"clientId","type":"uint256"}],"internalType":"struct GsnTypes.RelayData","name":"relayData","type":"tuple"}],"name":"calculateCharge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"charge","type":"uint256"}],"name":"calculateDevCharge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"depositFor","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_deprecationTime","type":"uint256"}],"name":"deprecateHub","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"relayManager","type":"address"}],"name":"escheatAbandonedRelayBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBatchGateway","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConfiguration","outputs":[{"components":[{"internalType":"uint256","name":"maxWorkerCount","type":"uint256"},{"internalType":"uint256","name":"gasReserve","type":"uint256"},{"internalType":"uint256","name":"postOverhead","type":"uint256"},{"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"internalType":"uint256","name":"minimumUnstakeDelay","type":"uint256"},{"internalType":"address","name":"devAddress","type":"address"},{"internalType":"uint8","name":"devFee","type":"uint8"},{"internalType":"uint80","name":"baseRelayFee","type":"uint80"},{"internalType":"uint16","name":"pctRelayFee","type":"uint16"}],"internalType":"struct IRelayHub.RelayHubConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCreationBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDeprecationTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"getMinimumStakePerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPenalizer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRelayRegistrar","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakeManager","outputs":[{"internalType":"contract IStakeManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"manager","type":"address"}],"name":"getWorkerCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"worker","type":"address"}],"name":"getWorkerManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct IForwarder.ForwardRequest","name":"request","type":"tuple"},{"components":[{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"uint256","name":"transactionCalldataGasUsed","type":"uint256"},{"internalType":"address","name":"relayWorker","type":"address"},{"internalType":"address","name":"paymaster","type":"address"},{"internalType":"address","name":"forwarder","type":"address"},{"internalType":"bytes","name":"paymasterData","type":"bytes"},{"internalType":"uint256","name":"clientId","type":"uint256"}],"internalType":"struct GsnTypes.RelayData","name":"relayData","type":"tuple"}],"internalType":"struct GsnTypes.RelayRequest","name":"relayRequest","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"approvalData","type":"bytes"},{"components":[{"internalType":"uint256","name":"acceptanceBudget","type":"uint256"},{"internalType":"uint256","name":"preRelayedCallGasLimit","type":"uint256"},{"internalType":"uint256","name":"postRelayedCallGasLimit","type":"uint256"},{"internalType":"uint256","name":"calldataSizeLimit","type":"uint256"}],"internalType":"struct IPaymaster.GasAndDataLimits","name":"gasAndDataLimits","type":"tuple"},{"internalType":"uint256","name":"totalInitialGas","type":"uint256"},{"internalType":"uint256","name":"maxPossibleGas","type":"uint256"}],"name":"innerRelayCall","outputs":[{"internalType":"enum IRelayHub.RelayCallStatus","name":"","type":"uint8"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isDeprecated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"relayManager","type":"address"}],"name":"isRelayEscheatable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"relayManager","type":"address"}],"name":"onRelayServerRegistered","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"relayWorker","type":"address"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"penalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxAcceptanceBudget","type":"uint256"},{"components":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct IForwarder.ForwardRequest","name":"request","type":"tuple"},{"components":[{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"uint256","name":"transactionCalldataGasUsed","type":"uint256"},{"internalType":"address","name":"relayWorker","type":"address"},{"internalType":"address","name":"paymaster","type":"address"},{"internalType":"address","name":"forwarder","type":"address"},{"internalType":"bytes","name":"paymasterData","type":"bytes"},{"internalType":"uint256","name":"clientId","type":"uint256"}],"internalType":"struct GsnTypes.RelayData","name":"relayData","type":"tuple"}],"internalType":"struct GsnTypes.RelayRequest","name":"relayRequest","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"approvalData","type":"bytes"}],"name":"relayCall","outputs":[{"internalType":"bool","name":"paymasterAccepted","type":"bool"},{"internalType":"uint256","name":"charge","type":"uint256"},{"internalType":"enum IRelayHub.RelayCallStatus","name":"status","type":"uint8"},{"internalType":"bytes","name":"returnValue","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"maxWorkerCount","type":"uint256"},{"internalType":"uint256","name":"gasReserve","type":"uint256"},{"internalType":"uint256","name":"postOverhead","type":"uint256"},{"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"internalType":"uint256","name":"minimumUnstakeDelay","type":"uint256"},{"internalType":"address","name":"devAddress","type":"address"},{"internalType":"uint8","name":"devFee","type":"uint8"},{"internalType":"uint80","name":"baseRelayFee","type":"uint80"},{"internalType":"uint16","name":"pctRelayFee","type":"uint16"}],"internalType":"struct IRelayHub.RelayHubConfig","name":"_config","type":"tuple"}],"name":"setConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20[]","name":"token","type":"address[]"},{"internalType":"uint256[]","name":"minimumStake","type":"uint256[]"}],"name":"setMinimumStakes","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":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"relayManager","type":"address"}],"name":"verifyRelayManagerStaked","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"versionHub","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address payable","name":"dest","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable[]","name":"dest","type":"address[]"},{"internalType":"uint256[]","name":"amount","type":"uint256[]"}],"name":"withdrawMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"}]

610120604052600019600c553480156200001857600080fd5b5060405162004cc038038062004cc08339810160408190526200003b9162000325565b62000046336200008b565b43610100526001600160601b0319606086811b821660805285811b821660a05284811b821660c05283901b1660e0526200008081620000db565b505050505062000487565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b031633146200013b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b60648160c0015160ff1610620001875760405162461bcd60e51b815260206004820152601060248201526f0c8caec40cccaca40e8dede40d0d2ced60831b604482015260640162000132565b8051600190815560208201516002556040808301516003556060830151600455608083015160055560a08301516006805460c086015160e08701516001600160501b0316600160a81b02600160a81b600160f81b031960ff909216600160a01b026001600160a81b03199093166001600160a01b039095169490941791909117169190911790556101008301516007805461ffff90921661ffff19909216919091179055517f4812ada68f7c2cdc9f4a4a09e157ea6b924e0ef40a4fa7aa074fa8f70b1e724791620002cb91815481526001820154602082015260028201546040820152600382015460608201526004820154608082015260058201546001600160a01b03811660a08084019190915260ff9082901c1660c083015260a81c6001600160501b031660e082015260069091015461ffff166101008201526101200190565b60405180910390a150565b8051620002e3816200046e565b919050565b805161ffff81168114620002e357600080fd5b80516001600160501b0381168114620002e357600080fd5b805160ff81168114620002e357600080fd5b60008060008060008587036101a08112156200034057600080fd5b86516200034d816200046e565b602088015190965062000360816200046e565b604088015190955062000373816200046e565b606088015190945062000386816200046e565b9250610120607f1982018113156200039d57600080fd5b620003a762000436565b91506080880151825260a0880151602083015260c0880151604083015260e08801516060830152610100808901516080840152620003e7828a01620002d6565b60a0840152620003fb6101408a0162000313565b60c08401526200040f6101608a01620002fb565b60e0840152620004236101808a01620002e8565b9083015250949793965091945092919050565b60405161012081016001600160401b03811182821017156200046857634e487b7160e01b600052604160045260246000fd5b60405290565b6001600160a01b03811681146200048457600080fd5b50565b60805160601c60a05160601c60c05160601c60e05160601c610100516147a96200051760003960006102420152600081816102eb015261081a0152600081816106f30152611781015260008181610423015261260e0152600081816105c80152818161078b0152818161090c015281816121e901528181612384015281816126ec01526127e701526147a96000f3fe6080604052600436106101f95760003560e01c80638e53548b1161010d578063ca64f9e7116100a0578063e6e22e121161006f578063e6e22e1214610664578063ebcd31ac14610684578063f2fde38b146106a4578063f3fef3a3146106c4578063f7908a74146106e457600080fd5b8063ca64f9e7146105b9578063d26152f9146105ec578063d904c7321461060c578063ddf737891461062e57600080fd5b8063b1a62e72116100dc578063b1a62e7214610518578063be7c76ad14610548578063c2da078614610581578063c7178230146105a157600080fd5b80638e53548b146104a55780639bcde3f3146104c5578063aa67c919146104e5578063af595dfc146104f857600080fd5b80636bd50cef11610190578063746d300c1161015f578063746d300c146103e657806375dc7b4e146104145780638a09fb56146104475780638ac3b845146104675780638da5cb5b1461048757600080fd5b80636bd50cef1461035957806370a082311461037b578063715018a6146103b157806372c1ab0c146103c657600080fd5b806345bdade7116101cc57806345bdade7146102a55780634f7de031146102ba57806351d85156146102dc57806359c4afc01461032357600080fd5b806301ffc9a7146101fe57806320ffd56d1461023357806339622167146102705780633c16e59a14610290575b600080fd5b34801561020a57600080fd5b5061021e610219366004613948565b610717565b60405190151581526020015b60405180910390f35b34801561023f57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405190815260200161022a565b34801561027c57600080fd5b5061021e61028b366004613692565b610769565b34801561029c57600080fd5b50600c54610262565b3480156102b157600080fd5b50610262610807565b3480156102c657600080fd5b506102da6102d5366004613692565b61080f565b005b3480156102e857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b03909116815260200161022a565b34801561032f57600080fd5b5061026261033e366004613692565b6001600160a01b03166000908152600a602052604090205490565b34801561036557600080fd5b5061036e61096b565b60405161022a9190614244565b34801561038757600080fd5b50610262610396366004613692565b6001600160a01b03166000908152600b602052604090205490565b3480156103bd57600080fd5b506102da610a4c565b3480156103d257600080fd5b506102da6103e1366004613788565b610a82565b3480156103f257600080fd5b50610406610401366004613af5565b610cab565b60405161022a929190614189565b34801561042057600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030b565b34801561045357600080fd5b506102da610462366004613850565b6110e8565b34801561047357600080fd5b50610262610482366004613c44565b611261565b34801561049357600080fd5b506000546001600160a01b031661030b565b3480156104b157600080fd5b506102626104c0366004613c5d565b611296565b3480156104d157600080fd5b506102da6104e0366004613a62565b61132c565b6102da6104f3366004613692565b6114f4565b34801561050457600080fd5b506102da610513366004613c44565b6115d5565b34801561052457600080fd5b50610538610533366004613ca0565b61167a565b60405161022a949392919061411d565b34801561055457600080fd5b5061030b610563366004613692565b6001600160a01b039081166000908152600960205260409020541690565b34801561058d57600080fd5b506102da61059c366004613714565b611fbd565b3480156105ad57600080fd5b50600c5442101561021e565b3480156105c557600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030b565b3480156105f857600080fd5b506102da610607366004613692565b6121a0565b34801561061857600080fd5b50610621612340565b60405161022a91906141a9565b34801561063a57600080fd5b50610262610649366004613692565b6001600160a01b031660009081526008602052604090205490565b34801561067057600080fd5b506102da61067f366004613692565b612360565b34801561069057600080fd5b506102da61069f3660046136db565b612603565b3480156106b057600080fd5b506102da6106bf366004613692565b61284b565b3480156106d057600080fd5b506102da6106df3660046136af565b6128e6565b3480156106f057600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030b565b60006001600160e01b031982166334f57c6760e01b148061074857506001600160e01b03198216630704183b60e11b145b8061076357506301ffc9a760e01b6001600160e01b03198316145b92915050565b604051633962216760e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063396221679060240160206040518083038186803b1580156107cf57600080fd5b505afa1580156107e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076391906138ea565b60005a905090565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461088c5760405162461bcd60e51b815260206004820152601d60248201527f63616c6c6572206973206e6f742072656c61792072656769737472617200000060448201526064015b60405180910390fd5b61089581612360565b6001600160a01b0381166000908152600a60205260409020546108ed5760405162461bcd60e51b815260206004820152601060248201526f6e6f2072656c617920776f726b65727360801b6044820152606401610883565b6040516346dcbf0b60e01b81526001600160a01b0382811660048301527f000000000000000000000000000000000000000000000000000000000000000016906346dcbf0b90602401600060405180830381600087803b15801561095057600080fd5b505af1158015610964573d6000803e3d6000fd5b5050505050565b6109d3604051806101200160405280600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600060ff16815260200160006001600160501b03168152602001600061ffff1681525090565b5060408051610120810182526001548152600254602082015260035491810191909152600454606082015260055460808201526006546001600160a01b03811660a0830152600160a01b810460ff1660c0830152600160a81b90046001600160501b031660e082015260075461ffff1661010082015290565b6000546001600160a01b03163314610a765760405162461bcd60e51b8152600401610883906141bc565b610a806000612989565b565b3360005b8251811015610ca5576001600160a01b0382166000908152600b60205260409020548351849083908110610abc57610abc6145f3565b6020026020010151811015610b085760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610883565b838281518110610b1a57610b1a6145f3565b602002602001015181610b2d9190614569565b6001600160a01b0384166000908152600b60205260408120919091558551869084908110610b5d57610b5d6145f3565b60200260200101516001600160a01b0316858481518110610b8057610b806145f3565b602002602001015160405160006040518083038185875af1925050503d8060008114610bc8576040519150601f19603f3d011682016040523d82523d6000602084013e610bcd565b606091505b5050905080610c115760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610883565b858381518110610c2357610c236145f3565b60200260200101516001600160a01b0316846001600160a01b03167fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb878681518110610c7157610c716145f3565b6020026020010151604051610c8891815260200190565b60405180910390a350508080610c9d906145ac565b915050610a86565b50505050565b60006060610d05604051806101200160405280600081526020016000815260200160008152602001600080191681526020016000151581526020016060815260200160608152602001606081526020016000151581525090565b610d0d610807565b81525a610d1a9086614569565b6020820152333014610d6e5760405162461bcd60e51b815260206004820152601a60248201527f4d7573742062652063616c6c65642062792052656c61794875620000000000006044820152606401610883565b600b6000610d7f60208e018e6143f1565b610d909060a0810190608001613692565b6001600160a01b0316815260208101919091526040908101600020548282015251622f977560e21b90610dd1908d908d908d908d908d908b90602401614346565b60408051601f19818403018152919052602080820180516001600160e01b03166001600160e01b03199094169390931790925260e0830152600090606090610e1b908e018e6143f1565b610e2c9060a0810190608001613692565b6001600160a01b031688602001358460e00151604051610e4c9190613f43565b60006040518083038160008787f1925050503d8060008114610e8a576040519150601f19603f3d011682016040523d82523d6000602084013e610e8f565b606091505b50909250905081610eae57610ea3816129d9565b610eae6002826129e5565b80806020019051810190610ec29190613972565b151561010085015260c08401525060009050610edf8c8c8c612a1e565b60a085015215156080840152905080610f0157610f0160038360a001516129e5565b8161010001518015610f1557508160800151155b15610f2957610f2960048360a001516129e5565b506376fa01c360e01b8160c001518260800151610f44610807565b8451610f509190614569565b8460200151610f5f9190614510565b8e8060200190610f6f91906143f1565b604051602401610f82949392919061414b565b60408051601f19818403018152919052602080820180516001600160e01b03166001600160e01b03199094169390931790925260e08301526000908190610fcb908e018e6143f1565b610fdc9060a0810190608001613692565b6001600160a01b031688604001358460e00151604051610ffc9190613f43565b60006040518083038160008787f1925050503d806000811461103a576040519150601f19603f3d011682016040523d82523d6000602084013e61103f565b606091505b509150915081611054576110546005826129e5565b50506040810151600b600061106c60208f018f6143f1565b61107d9060a0810190608001613692565b6001600160a01b03166001600160a01b031681526020019081526020016000205410156110be576110be6006604051806020016040528060008152506129e5565b80608001516110ce5760016110d1565b60005b8160a0015192509250509850989650505050505050565b6000546001600160a01b031633146111125760405162461bcd60e51b8152600401610883906141bc565b80518251146111635760405162461bcd60e51b815260206004820152601e60248201527f7365744d696e696d756d5374616b65733a2077726f6e67206c656e67746800006044820152606401610883565b60005b825181101561125c57818181518110611181576111816145f3565b60200260200101516008600085848151811061119f5761119f6145f3565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055507ffb7510fe755f485459ee8ed619d4a0addc092c230ff47e760a62aeba78ebb9e38382815181106111fe576111fe6145f3565b6020026020010151838381518110611218576112186145f3565b60200260200101516040516112429291906001600160a01b03929092168252602082015260400190565b60405180910390a180611254816145ac565b915050611166565b505050565b600654600090600160a01b900460ff1661127d57506000919050565b600654606490600160a01b900460ff1683020492915050565b6000808235602084013514156112ae575060006112b1565b50485b60006112cd84356112c83a81602089013587614510565b612c02565b6007549091506064906112e49061ffff16826144ea565b61ffff166112f2838861454a565b6112fc919061454a565b6113069190614528565b6006546113239190600160a81b90046001600160501b0316614510565b95945050505050565b6000546001600160a01b031633146113565760405162461bcd60e51b8152600401610883906141bc565b60648160c0015160ff16106113a05760405162461bcd60e51b815260206004820152601060248201526f0c8caec40cccaca40e8dede40d0d2ced60831b6044820152606401610883565b8051600190815560208201516002556040808301516003556060830151600455608083015160055560a08301516006805460c086015160e08701516001600160501b0316600160a81b0269ffffffffffffffffffff60a81b1960ff909216600160a01b026001600160a81b03199093166001600160a01b039095169490941791909117169190911790556101008301516007805461ffff90921661ffff19909216919091179055517f4812ada68f7c2cdc9f4a4a09e157ea6b924e0ef40a4fa7aa074fa8f70b1e7247916114e991815481526001820154602082015260028201546040820152600382015460608201526004820154608082015260058201546001600160a01b03811660a08084019190915260ff9082901c1660c08301526001600160501b0360a89190911c1660e082015260069091015461ffff166101008201526101200190565b60405180910390a150565b61150e6001600160a01b0382166370d596f560e11b612c1a565b61155a5760405162461bcd60e51b815260206004820181905260248201527f746172676574206973206e6f7420612076616c696420495061796d61737465726044820152606401610883565b6001600160a01b0381166000908152600b60205260409020543490611580908290614510565b6001600160a01b0383166000818152600b6020908152604091829020939093555183815233927f8752a472e571a816aea92eec8dae9baf628e840f4929fbcc2d155e6233ff68a7910160405180910390a35050565b6000546001600160a01b031633146115ff5760405162461bcd60e51b8152600401610883906141bc565b600c5442106116455760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e4819195c1c9958d85d195960721b6044820152606401610883565b600c8190556040518181527f1c0aa0c666483fbf0cf795d9d646ea3552d1e3008162ba9ab1d6d6dfd8c6ec6b906020016114e9565b6000806000606061168961343d565b611691610807565b60408201526116a18a8a8a612c36565b6101e0820152600c5442106116e95760405162461bcd60e51b815260206004820152600e60248201526d1a1d588819195c1c9958d85d195960921b6044820152606401610883565b60046116f58b806143db565b6117039060a0810190614395565b90501015611712576000611767565b61176761171f8b806143db565b61172d9060a0810190614395565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509250612c9b915050565b6001600160e01b0319166020820152336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148015906117ae57503215155b156118c257876118005760405162461bcd60e51b815260206004820181905260248201527f6d697373696e67207369676e6174757265206f722062616420676174657761796044820152606401610883565b33321461184f5760405162461bcd60e51b815260206004820152601860248201527f72656c617920776f726b6572206d75737420626520454f4100000000000000006044820152606401610883565b61185c60208b018b6143f1565b61186d906080810190606001613692565b6001600160a01b0316336001600160a01b0316146118c25760405162461bcd60e51b81526020600482015260126024820152712737ba1030903934b3b43a103bb7b935b2b960711b6044820152606401610883565b321561196057600960006118d960208d018d6143f1565b6118ea906080810190606001613692565b6001600160a01b039081168252602082019290925260400160002054166101c082018190526119525760405162461bcd60e51b81526020600482015260146024820152732ab735b737bbb7103932b630bc903bb7b935b2b960611b6044820152606401610883565b611960816101c00151612360565b61196f8b8b8360400151612d0b565b61010083015260a08201526119878a8a8a8a8a612f95565b60025460405a61199890603f61454a565b6119a29190614528565b6119ac9190614569565b6101208201526119ba610807565b81610140018181525050600060016002015460016003015483610120015184604001518e80602001906119ed91906143f1565b604001356119fb9190614510565b611a059190614510565b611a0f9190614510565b611a199190614510565b9050600080306001600160a01b031684610120015163746d300c60e01b8f8f8f8f8f8b60a00151611a48610807565b611a52908d614569565b8d6101000151604051602401611a6f9897969594939291906142c6565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611aad9190613f43565b60006040518083038160008787f1925050503d8060008114611aeb576040519150601f19603f3d011682016040523d82523d6000602084013e611af0565b606091505b5081151586529092509050611b03610807565b846101400151611b139190614569565b60e08501528051611b2d90820160209081019083016139bf565b8560c00186608001829052826006811115611b4a57611b4a6145dd565b6006811115611b5b57611b5b6145dd565b9052505060808401515115611bac577fa1478a4242848419db824250a0dddc645dca0d6a9b12ab1fd79b00145a0ba98e8460c001518560800151604051611ba3929190614189565b60405180910390a15b505081519050611d125760028160c001516006811115611bce57611bce6145dd565b1480611c3d5750611be260208b018b6143f1565b60a082015151611bf6916040013590614510565b8160e0015111158015611c3d575060038160c001516006811115611c1c57611c1c6145dd565b1480611c3d575060048160c001516006811115611c3b57611c3b6145dd565b145b15611d12576101e0810151611c5560208c018c6143f1565b611c669060a0810190608001613692565b6101c08301516001600160a01b0391821691167f0c47510cb900901afca7c9e926892582a36fd3bb7f908142ccf0fb4382a2b684611ca48e806143db565b611cb2906020810190613692565b611cbc8f806143db565b611ccd906040810190602001613692565b3387602001518860e001518960800151604051611cef96959493929190614048565b60405180910390a46000808260c001518360800151945094509450945050611fb0565b600454611d1d610807565b8260400151611d2c9190614569565b611d3960208d018d6143f1565b60400135611d479190614510565b611d519190614510565b6101608201819052611d6a906104c060208d018d6143f1565b9350611d7584611261565b61018082015283600b6000611d8d60208e018e6143f1565b611d9e9060a0810190608001613692565b6001600160a01b03166001600160a01b0316815260200190815260200160002054611dc99190614569565b600b6000611dda60208e018e6143f1565b611deb9060a0810190608001613692565b6001600160a01b03168152602081019190915260400160002055610180810151611e159085614569565b6101c08201516001600160a01b03166000908152600b6020526040902054611e3d9190614510565b6101c08201516001600160a01b03166000908152600b602052604090205561018081015115611ead576101808101516006546001600160a01b03166000908152600b6020526040902054611e919190614510565b6006546001600160a01b03166000908152600b60205260409020555b6000611eb98b806143db565b611ec7906020810190613692565b90506000611ed58c806143db565b611ee6906040810190602001613692565b90506000611ef760208e018e6143f1565b611f089060a0810190608001613692565b9050836101e00151336001600160a01b0316856101c001516001600160a01b03167fd51ac07012398c2059ec53c6005fa8639657917bd2dbd72bc489a3c0eaaa7f168686868a602001518b60c001518f604051611f6a96959493929190613ffa565b60405180910390a450505032611f935760c0810151608090910151600195509092509050611fb0565b60c001516040805160208101909152600081526001955090925090505b9650965096509692505050565b336000818152600a6020526040812054611fd8908490614510565b6001600160a01b0383166000908152600a6020526040902081905560015490915081111561203b5760405162461bcd60e51b815260206004820152601060248201526f746f6f206d616e7920776f726b65727360801b6044820152606401610883565b61204482612360565b60005b83811015612154576000600981878785818110612066576120666145f3565b905060200201602081019061207b9190613692565b6001600160a01b03908116825260208201929092526040016000205416146120e55760405162461bcd60e51b815260206004820152601960248201527f7468697320776f726b6572206861732061206d616e61676572000000000000006044820152606401610883565b82600960008787858181106120fc576120fc6145f3565b90506020020160208101906121119190613692565b6001600160a01b039081168252602082019290925260400160002080546001600160a01b031916929091169190911790558061214c816145ac565b915050612047565b50816001600160a01b03167febf4a9bffb39f7c5dbf3f65540183b9381ae226ac3d0a45b4cad484713bd4a28858584604051612192939291906140c7565b60405180910390a250505050565b6000546001600160a01b031633146121ca5760405162461bcd60e51b8152600401610883906141bc565b604051633962216760e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063396221679060240160206040518083038186803b15801561222b57600080fd5b505afa15801561223f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226391906138ea565b6122af5760405162461bcd60e51b815260206004820181905260248201527f72656c617920736572766572206e6f74206573636865617461626c65207965746044820152606401610883565b6001600160a01b038082166000908152600b602052604080822080549083905560065490931682529020546122e5908290614510565b6006546001600160a01b039081166000908152600b60209081526040918290209390935551838152908416917f3fb672a061b9c3ab083062a9a8ff532d341e5fa42145b91f3922a711ae135659910160405180910390a25050565b606060405180606001604052806022815260200161469660229139905090565b60405163c345315360e01b81526001600160a01b03828116600483015260009182917f0000000000000000000000000000000000000000000000000000000000000000169063c3453153906024016101006040518083038186803b1580156123c757600080fd5b505afa1580156123db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ff9190613bb8565b60a0820180516001600160a01b03908116600090815260086020526040902054915193955091935091166124705760405162461bcd60e51b81526020600482015260186024820152771c995b185e481b585b9859d95c881b9bdd081cdd185ad95960421b6044820152606401610883565b82518111156124c15760405162461bcd60e51b815260206004820152601960248201527f7374616b6520616d6f756e7420697320746f6f20736d616c6c000000000000006044820152606401610883565b8061250e5760405162461bcd60e51b815260206004820152601f60248201527f7374616b696e67207468697320746f6b656e20697320666f7262696464656e006044820152606401610883565b600554602084015110156125645760405162461bcd60e51b815260206004820152601a60248201527f756e7374616b652064656c617920697320746f6f20736d616c6c0000000000006044820152606401610883565b6040830151156125b65760405162461bcd60e51b815260206004820152601860248201527f7374616b6520686173206265656e2077697468647261776e00000000000000006044820152606401610883565b81610ca55760405162461bcd60e51b815260206004820181905260248201527f7468697320687562206973206e6f7420617574686f72697a656420627920534d6044820152606401610883565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461266b5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103832b730b634bd32b960991b6044820152606401610883565b6001600160a01b0380831660009081526009602052604090205416806126ca5760405162461bcd60e51b81526020600482015260146024820152732ab735b737bbb7103932b630bc903bb7b935b2b960611b6044820152606401610883565b60405163c345315360e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063c3453153906024016101006040518083038186803b15801561273157600080fd5b505afa158015612745573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127699190613bb8565b5080519091506127b65760405162461bcd60e51b81526020600482015260186024820152771c995b185e481b585b9859d95c881b9bdd081cdd185ad95960421b6044820152606401610883565b805160405163026822bd60e21b81526001600160a01b038481166004830152858116602483015260448201929092527f0000000000000000000000000000000000000000000000000000000000000000909116906309a08af490606401600060405180830381600087803b15801561282d57600080fd5b505af1158015612841573d6000803e3d6000fd5b5050505050505050565b6000546001600160a01b031633146128755760405162461bcd60e51b8152600401610883906141bc565b6001600160a01b0381166128da5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610883565b6128e381612989565b50565b604080516001808252818301909252600091602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337019050509050828260008151811061293f5761293f6145f3565b602002602001018181525050838160008151811061295f5761295f6145f3565b60200260200101906001600160a01b031690816001600160a01b031681525050610ca58183610a82565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6128e3816104006130b4565b600082826040516020016129fa929190614189565b6040516020818303038152906040529050612a14816129d9565b8051602082018181fd5b60008060606000612a2e876130c5565b90506000612a58612a4260208a018a6143f1565b612a539060c081019060a001613692565b613104565b9050612a6760208901896143f1565b612a789060c081019060a001613692565b6001600160a01b031663e024dc7f60e01b612a938a806143db565b836040518060400160405280600c81526020016b14995b185e54995c5d595cdd60a21b8152506040518060a0016040528060618152602001614635606191396040518060e0016040528060bc81526020016146b860bc9139604051602001612afb9190613fbe565b60408051601f1981840301815290829052612b1a939291602001613f5f565b60405160208183030381529060405280519060200120868c8c604051602401612b48969594939291906141f1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612b869190613f43565b6000604051808303816000865af19150503d8060008114612bc3576040519150601f19603f3d011682016040523d82523d6000602084013e612bc8565b606091505b5090955092508415612bee5782806020019051810190612be89190613905565b90945092505b612bf7836129d9565b505093509350939050565b6000818310612c115781612c13565b825b9392505050565b6000612c258361317d565b8015612c135750612c1383836131b0565b60006001600160e01b03612c4a85806143db565b612c58906020810190613692565b612c6286806143db565b608001358585604051602001612c7b949392919061409f565b604051602081830303815290604052805190602001201690509392505050565b6000612ca8826004614510565b83511015612cf85760405162461bcd60e51b815260206004820152601a60248201527f726561644279746573343a206461746120746f6f2073686f72740000000000006044820152606401610883565b5001602001516001600160e01b03191690565b612d366040518060800160405280600081526020016000815260200160008152602001600081525090565b6000612d4560208501856143f1565b612d569060a0810190608001613692565b6001600160a01b031663b039a88f61c3506040518263ffffffff1660e01b815260040160806040518083038187803b158015612d9157600080fd5b5086fa158015612da5573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612dca91906139fd565b6060810151909250361115612e215760405162461bcd60e51b815260206004820152601760248201527f6d73672e64617461206578636565646564206c696d69740000000000000000006044820152606401610883565b8151851015612e725760405162461bcd60e51b815260206004820152601a60248201527f616363657074616e63652062756467657420746f6f20686967680000000000006044820152606401610883565b602082015182511015612ec75760405162461bcd60e51b815260206004820152601960248201527f616363657074616e63652062756467657420746f6f206c6f77000000000000006044820152606401610883565b82612ed560208601866143f1565b60400135612ee39190614510565b90506000612ef8826104c060208801886143f1565b9050600b6000612f0b60208801886143f1565b612f1c9060a0810190608001613692565b6001600160a01b03166001600160a01b0316815260200190815260200160002054811115612f8c5760405162461bcd60e51b815260206004820152601960248201527f5061796d61737465722062616c616e636520746f6f206c6f77000000000000006044820152606401610883565b50935093915050565b6000612fba612fa760208801886143f1565b612fb59060c0810190614395565b613299565b612fd5612fc788806143db565b612fb59060a0810190614395565b612fdf8585613299565b612fe98888613299565b612ff5906102a4614510565b612fff9190614510565b6130099190614510565b6130139190614510565b905060418411156130665760405162461bcd60e51b815260206004820152601860248201527f696e76616c6964207369676e6174757265206c656e67746800000000000000006044820152606401610883565b3681146130ac5760405162461bcd60e51b81526020600482015260146024820152736578747261206d73672e6461746120627974657360601b6044820152606401610883565b505050505050565b80825111156130c1578082525b5050565b60606130dc6130d760208401846143f1565b6132bf565b6040516020016130ee91815260200190565b6040516020818303038152906040529050919050565b6040805160c0810182526017608082019081527f47534e2052656c61796564205472616e73616374696f6e00000000000000000060a083015281528151808301835260018152603360f81b60208083019190915282015260009161076391908101468152602001846001600160a01b03168152506133bd565b6000613190826301ffc9a760e01b6131b0565b801561076357506131a9826001600160e01b03196131b0565b1592915050565b604080516001600160e01b0319831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03166301ffc9a760e01b179052905160009190829081906001600160a01b0387169061753090613217908690613f43565b6000604051808303818686fa925050503d8060008114613253576040519150601f19603f3d011682016040523d82523d6000602084013e613258565b606091505b50915091506020815110156132735760009350505050610763565b81801561328f57508080602001905181019061328f91906138ea565b9695505050505050565b60006132a8601f600019614569565b6132b383601f614510565b612c1391166020614510565b60006040518060e0016040528060bc81526020016146b860bc913980516020918201209083359084013560408501356132fe6080870160608801613692565b61330e60a0880160808901613692565b61331e60c0890160a08a01613692565b61332b60c08a018a614395565b604051613339929190613f33565b6040519081900381206133a0989796959493929160e08c0135906020019889526020890197909752604088019590955260608701939093526001600160a01b039182166080870152811660a08601521660c084015260e08301526101008201526101200190565b604051602081830303815290604052805190602001209050919050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f826000015180519060200120836020015180519060200120846040015185606001516040516020016133a09594939291909485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b60405180610200016040528060001515815260200160006001600160e01b03191681526020016000815260200160608152602001606081526020016134a36040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016060815260200160006001600160a01b03168152602001600080191681525090565b80356135068161461f565b919050565b600082601f83011261351c57600080fd5b8135602061353161352c83614482565b614452565b80838252828201915082860187848660051b890101111561355157600080fd5b60005b8581101561357057813584529284019290840190600101613554565b5090979650505050505050565b8051801515811461350657600080fd5b60008083601f84011261359f57600080fd5b5081356001600160401b038111156135b657600080fd5b6020830191508360208285010111156135ce57600080fd5b9250929050565b600082601f8301126135e657600080fd5b81516001600160401b038111156135ff576135ff614609565b613612601f8201601f1916602001614452565b81815284602083860101111561362757600080fd5b613638826020830160208701614580565b949350505050565b60006040828403121561365257600080fd5b50919050565b803561ffff8116811461350657600080fd5b803560ff8116811461350657600080fd5b80356001600160501b038116811461350657600080fd5b6000602082840312156136a457600080fd5b8135612c138161461f565b600080604083850312156136c257600080fd5b82356136cd8161461f565b946020939093013593505050565b600080604083850312156136ee57600080fd5b82356136f98161461f565b915060208301356137098161461f565b809150509250929050565b6000806020838503121561372757600080fd5b82356001600160401b038082111561373e57600080fd5b818501915085601f83011261375257600080fd5b81358181111561376157600080fd5b8660208260051b850101111561377657600080fd5b60209290920196919550909350505050565b6000806040838503121561379b57600080fd5b82356001600160401b03808211156137b257600080fd5b818501915085601f8301126137c657600080fd5b813560206137d661352c83614482565b8083825282820191508286018a848660051b89010111156137f657600080fd5b600096505b8487101561382257803561380e8161461f565b8352600196909601959183019183016137fb565b509650508601359250508082111561383957600080fd5b506138468582860161350b565b9150509250929050565b6000806040838503121561386357600080fd5b82356001600160401b038082111561387a57600080fd5b818501915085601f83011261388e57600080fd5b8135602061389e61352c83614482565b8083825282820191508286018a848660051b89010111156138be57600080fd5b600096505b848710156138225780356138d68161461f565b8352600196909601959183019183016138c3565b6000602082840312156138fc57600080fd5b612c138261357d565b6000806040838503121561391857600080fd5b6139218361357d565b915060208301516001600160401b0381111561393c57600080fd5b613846858286016135d5565b60006020828403121561395a57600080fd5b81356001600160e01b031981168114612c1357600080fd5b6000806040838503121561398557600080fd5b82516001600160401b0381111561399b57600080fd5b6139a7858286016135d5565b9250506139b66020840161357d565b90509250929050565b600080604083850312156139d257600080fd5b8251600781106139e157600080fd5b60208401519092506001600160401b0381111561393c57600080fd5b600060808284031215613a0f57600080fd5b604051608081018181106001600160401b0382111715613a3157613a31614609565b8060405250825181526020830151602082015260408301516040820152606083015160608201528091505092915050565b60006101208284031215613a7557600080fd5b613a7d614407565b8235815260208301356020820152604083013560408201526060830135606082015260808301356080820152613ab560a084016134fb565b60a0820152613ac660c0840161366a565b60c0820152613ad760e0840161367b565b60e0820152610100613aea818501613658565b908201529392505050565b600080600080600080600080888a03610120811215613b1357600080fd5b89356001600160401b0380821115613b2a57600080fd5b613b368d838e01613640565b9a5060208c0135915080821115613b4c57600080fd5b613b588d838e0161358d565b909a50985060408c0135915080821115613b7157600080fd5b50613b7e8c828d0161358d565b9097509550506080605f1982011215613b9657600080fd5b5096999598509396929550909360608301935060e08301359261010001359150565b600080828403610100811215613bcd57600080fd5b60e0811215613bdb57600080fd5b50613be4614430565b835181526020840151602082015260408401516040820152606084015160608201526080840151608082015260a0840151613c1e8161461f565b60a082015260c0840151613c318161461f565b60c082015291506139b660e0840161357d565b600060208284031215613c5657600080fd5b5035919050565b60008060408385031215613c7057600080fd5b8235915060208301356001600160401b03811115613c8d57600080fd5b8301610100818603121561370957600080fd5b60008060008060008060808789031215613cb957600080fd5b8635955060208701356001600160401b0380821115613cd757600080fd5b613ce38a838b01613640565b96506040890135915080821115613cf957600080fd5b613d058a838b0161358d565b90965094506060890135915080821115613d1e57600080fd5b50613d2b89828a0161358d565b979a9699509497509295939492505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60008151808452613d7e816020860160208601614580565b601f01601f19169290920160200192915050565b60078110613db057634e487b7160e01b600052602160045260246000fd5b9052565b60008135613dc18161461f565b6001600160a01b039081168452602083013590613ddd8261461f565b166020840152604082810135908401526060808301359084015260808083013590840152613e0e60a08301836144a5565b60e060a0860152613e2360e086018284613d3d565b91505060c083013560c08501528091505092915050565b60006101008235845260208301356020850152604083013560408501526060830135613e658161461f565b6001600160a01b039081166060860152608084013590613e848261461f565b16608085015260a0830135613e988161461f565b6001600160a01b031660a0850152613eb360c08401846144a5565b8260c0870152613ec68387018284613d3d565b9250505060e083013560e08501528091505092915050565b6000813582360360de1981018212613ef557600080fd5b60408552613f0860408601858401613db4565b9150602084013560fe1982018112613f1f57600080fd5b858303602087015261328f83868301613e3a565b8183823760009101908152919050565b60008251613f55818460208701614580565b9190910192915050565b60008451613f71818460208901614580565b600560fb1b9083019081528451613f8f816001840160208901614580565b600b60fa1b600192909101918201528351613fb1816002840160208801614580565b0160020195945050505050565b7352656c6179446174612072656c6179446174612960601b815260008251613fed816014850160208701614580565b9190910160140192915050565b6001600160a01b0387811682528681166020830152851660408201526001600160e01b03198416606082015260c081016140376080830185613d92565b8260a0830152979650505050505050565b6001600160a01b0387811682528681166020830152851660408201526001600160e01b0319841660608201526080810183905260c060a0820181905260009061409390830184613d66565b98975050505050505050565b60018060a01b038516815283602082015260606040820152600061328f606083018486613d3d565b6040808252810183905260008460608301825b8681101561410a5782356140ed8161461f565b6001600160a01b03168252602092830192909101906001016140da565b5060209390930193909352509392505050565b84151581528360208201526141356040820184613d92565b60806060820152600061328f6080830184613d66565b60808152600061415e6080830187613d66565b8515156020840152846040840152828103606084015261417e8185613e3a565b979650505050505050565b6141938184613d92565b6040602082015260006136386040830184613d66565b602081526000612c136020830184613d66565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60a08152600061420460a0830189613db4565b87602084015286604084015282810360608401526142228187613d66565b90508281036080840152614237818587613d3d565b9998505050505050505050565b600061012082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260018060a01b0360a08401511660a083015260ff60c08401511660c083015260e08301516142b260e08401826001600160501b03169052565b506101009283015161ffff16919092015290565b60006101208083526142da8184018c613ede565b905082810360208401526142ef818a8c613d3d565b9050828103604084015261430481888a613d3d565b9150508451606083015260208501516080830152604085015160a0830152606085015160c08301528360e0830152826101008301529998505050505050505050565b6080815260006143596080830189613ede565b828103602084015261436c81888a613d3d565b90508281036040840152614381818688613d3d565b915050826060830152979650505050505050565b6000808335601e198436030181126143ac57600080fd5b8301803591506001600160401b038211156143c657600080fd5b6020019150368190038213156135ce57600080fd5b6000823560de19833603018112613f5557600080fd5b6000823560fe19833603018112613f5557600080fd5b60405161012081016001600160401b038111828210171561442a5761442a614609565b60405290565b60405160e081016001600160401b038111828210171561442a5761442a614609565b604051601f8201601f191681016001600160401b038111828210171561447a5761447a614609565b604052919050565b60006001600160401b0382111561449b5761449b614609565b5060051b60200190565b6000808335601e198436030181126144bc57600080fd5b83016020810192503590506001600160401b038111156144db57600080fd5b8036038313156135ce57600080fd5b600061ffff808316818516808303821115614507576145076145c7565b01949350505050565b60008219821115614523576145236145c7565b500190565b60008261454557634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615614564576145646145c7565b500290565b60008282101561457b5761457b6145c7565b500390565b60005b8381101561459b578181015183820152602001614583565b83811115610ca55750506000910152565b60006000198214156145c0576145c06145c7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146128e357600080fdfe616464726573732066726f6d2c6164647265737320746f2c75696e743235362076616c75652c75696e74323536206761732c75696e74323536206e6f6e63652c627974657320646174612c75696e743235362076616c6964556e74696c54696d65332e302e302d626574612e302b6f70656e67736e2e6875622e6972656c617968756252656c6179446174612875696e74323536206d61784665655065724761732c75696e74323536206d61785072696f726974794665655065724761732c75696e74323536207472616e73616374696f6e43616c6c64617461476173557365642c616464726573732072656c6179576f726b65722c61646472657373207061796d61737465722c6164647265737320666f727761726465722c6279746573207061796d6173746572446174612c75696e7432353620636c69656e74496429a2646970667358221220ef137c0ceaa4ff6388385b5911e82c255a8a52c5ebfeb89aed96950deeb92c3664736f6c6343000807003300000000000000000000000031638c4ae939db4cdfda003b7bc1d205d13d11a6000000000000000000000000202dda1b1159ebca278f48802a2884c0eaffefe70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000409893be00ab9cc726a2aab7ffb08e33009b3c90000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000004029000000000000000000000000000000000000000000000000000000000000d92c0000000000000000000000000000000000000000000000000000000000003a98000000000000000000000000d21934ed8eaf27a67f0a70042af50a1d6d195e81000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000000000000000000032

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000031638c4ae939db4cdfda003b7bc1d205d13d11a6000000000000000000000000202dda1b1159ebca278f48802a2884c0eaffefe70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000409893be00ab9cc726a2aab7ffb08e33009b3c90000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000004029000000000000000000000000000000000000000000000000000000000000d92c0000000000000000000000000000000000000000000000000000000000003a98000000000000000000000000d21934ed8eaf27a67f0a70042af50a1d6d195e81000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000000000000000000032

-----Decoded View---------------
Arg [0] : _stakeManager (address): 0x31638c4ae939db4cdfda003b7bc1d205d13d11a6
Arg [1] : _penalizer (address): 0x202dda1b1159ebca278f48802a2884c0eaffefe7
Arg [2] : _batchGateway (address): 0x0000000000000000000000000000000000000000
Arg [3] : _relayRegistrar (address): 0x409893be00ab9cc726a2aab7ffb08e33009b3c90
Arg [4] : _config (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 00000000000000000000000031638c4ae939db4cdfda003b7bc1d205d13d11a6
Arg [1] : 000000000000000000000000202dda1b1159ebca278f48802a2884c0eaffefe7
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 000000000000000000000000409893be00ab9cc726a2aab7ffb08e33009b3c90
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [5] : 00000000000000000000000000000000000000000000000000000000000186a0
Arg [6] : 0000000000000000000000000000000000000000000000000000000000004029
Arg [7] : 000000000000000000000000000000000000000000000000000000000000d92c
Arg [8] : 0000000000000000000000000000000000000000000000000000000000003a98
Arg [9] : 000000000000000000000000d21934ed8eaf27a67f0a70042af50a1d6d195e81
Arg [10] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [11] : 00000000000000000000000000000000000000000000000000038d7ea4c68000
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000032


Deployed ByteCode Sourcemap

1193:23595:9:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4964:282;;;;;;;;;;-1:-1:-1;4964:282:9;;;;;:::i;:::-;;:::i;:::-;;;23659:14:21;;23652:22;23634:41;;23622:2;23607:18;4964:282:9;;;;;;;;3604:113;;;;;;;;;;-1:-1:-1;3697:13:9;3604:113;;;24322:25:21;;;24310:2;24295:18;3604:113:9;24176:177:21;24020:154:9;;;;;;;;;;-1:-1:-1;24020:154:9;;;;;:::i;:::-;;:::i;3753:110::-;;;;;;;;;;-1:-1:-1;3841:15:9;;3753:110;;24679:107;;;;;;;;;;;;;:::i;5282:337::-;;;;;;;;;;-1:-1:-1;5282:337:9;;;;;:::i;:::-;;:::i;:::-;;4319:108;;;;;;;;;;-1:-1:-1;4406:14:9;4319:108;;;-1:-1:-1;;;;;20233:32:21;;;20215:51;;20203:2;20188:18;4319:108:9;20069:203:21;4804:126:9;;;;;;;;;;-1:-1:-1;4804:126:9;;;;;:::i;:::-;-1:-1:-1;;;;;4903:20:9;4877:7;4903:20;;;:11;:20;;;;;;;4804:126;1831:111;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;6767:116::-;;;;;;;;;;-1:-1:-1;6767:116:9;;;;;:::i;:::-;-1:-1:-1;;;;;6860:16:9;6834:7;6860:16;;;:8;:16;;;;;;;6767:116;1668:101:0;;;;;;;;;;;;;:::i;7271:565:9:-;;;;;;;;;;-1:-1:-1;7271:565:9;;;;;:::i;:::-;;:::i;16511:4108::-;;;;;;;;;;-1:-1:-1;16511:4108:9;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;4045:98::-;;;;;;;;;;-1:-1:-1;4127:9:9;4045:98;;2352:404;;;;;;;;;;-1:-1:-1;2352:404:9;;;;;:::i;:::-;;:::i;21141:281::-;;;;;;;;;;-1:-1:-1;21141:281:9;;;;;:::i;:::-;;:::i;1036:85:0:-;;;;;;;;;;-1:-1:-1;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;1036:85;;21458:561:9;;;;;;;;;;-1:-1:-1;21458:561:9;;;;;:::i;:::-;;:::i;1978:216::-;;;;;;;;;;-1:-1:-1;1978:216:9;;;;;:::i;:::-;;:::i;6403:328::-;;;;;;:::i;:::-;;:::i;22810:226::-;;;;;;;;;;-1:-1:-1;22810:226:9;;;;;:::i;:::-;;:::i;9652:6357::-;;;;;;;;;;-1:-1:-1;9652:6357:9;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;4638:130::-;;;;;;;;;;-1:-1:-1;4638:130:9;;;;;:::i;:::-;-1:-1:-1;;;;;4738:23:9;;;4712:7;4738:23;;;:15;:23;;;;;;;;4638:130;5655:712;;;;;;;;;;-1:-1:-1;5655:712:9;;;;;:::i;:::-;;:::i;23072:118::-;;;;;;;;;;-1:-1:-1;23168:15:9;;23149;:34;;23072:118;;3899:110;;;;;;;;;;-1:-1:-1;3990:12:9;3899:110;;24210:433;;;;;;;;;;-1:-1:-1;24210:433:9;;;;;:::i;:::-;;:::i;1438:134::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;4463:139::-;;;;;;;;;;-1:-1:-1;4463:139:9;;;;;:::i;:::-;-1:-1:-1;;;;;4568:27:9;4542:7;4568:27;;;:20;:27;;;;;;;4463:139;22055:719;;;;;;;;;;-1:-1:-1;22055:719:9;;;;;:::i;:::-;;:::i;23425:559::-;;;;;;;;;;-1:-1:-1;23425:559:9;;;;;:::i;:::-;;:::i;1918:198:0:-;;;;;;;;;;-1:-1:-1;1918:198:0;;;;;:::i;:::-;;:::i;6919:316:9:-;;;;;;;;;;-1:-1:-1;6919:316:9;;;;;:::i;:::-;;:::i;4179:104::-;;;;;;;;;;-1:-1:-1;4264:12:9;4179:104;;4964:282;5066:4;-1:-1:-1;;;;;;5089:42:9;;-1:-1:-1;;;5089:42:9;;:98;;-1:-1:-1;;;;;;;5147:40:9;;-1:-1:-1;;;5147:40:9;5089:98;:150;;;-1:-1:-1;;;;;;;;;;937:40:5;;;5203:36:9;5082:157;4964:282;-1:-1:-1;;4964:282:9:o;24020:154::-;24122:45;;-1:-1:-1;;;24122:45:9;;-1:-1:-1;;;;;20233:32:21;;;24122:45:9;;;20215:51:21;24100:4:9;;24122:12;:31;;;;;;20188:18:21;;24122:45:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;24679:107::-;24745:7;24770:9;24763:16;;24679:107;:::o;5282:337::-;5373:10;-1:-1:-1;;;;;5387:14:9;5373:28;;5365:70;;;;-1:-1:-1;;;5365:70:9;;28531:2:21;5365:70:9;;;28513:21:21;28570:2;28550:18;;;28543:30;28609:31;28589:18;;;28582:59;28658:18;;5365:70:9;;;;;;;;;5445:38;5470:12;5445:24;:38::i;:::-;-1:-1:-1;;;;;5501:25:9;;5529:1;5501:25;;;:11;:25;;;;;;5493:58;;;;-1:-1:-1;;;5493:58:9;;33200:2:21;5493:58:9;;;33182:21:21;33239:2;33219:18;;;33212:30;-1:-1:-1;;;33258:18:21;;;33251:46;33314:18;;5493:58:9;32998:340:21;5493:58:9;5561:51;;-1:-1:-1;;;5561:51:9;;-1:-1:-1;;;;;20233:32:21;;;5561:51:9;;;20215::21;5561:12:9;:37;;;;20188:18:21;;5561:51:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5282:337;:::o;1831:111::-;1889:21;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1889:21:9;-1:-1:-1;1922:13:9;;;;;;;;1929:6;1922:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1922:13:9;;;;;;-1:-1:-1;;;1922:13:9;;;;;;;;-1:-1:-1;;;1922:13:9;;-1:-1:-1;;;;;1922:13:9;;;;;;;;;;;;;;1831:111::o;1668:101:0:-;1082:7;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;1732:30:::1;1759:1;1732:18;:30::i;:::-;1668:101::o:0;7271:565:9:-;7413:10;7379:23;7434:396;7458:6;:13;7454:1;:17;7434:396;;;-1:-1:-1;;;;;7510:17:9;;7492:15;7510:17;;;:8;:17;;;;;;7560:9;;:6;;7567:1;;7560:9;;;;;;:::i;:::-;;;;;;;7549:7;:20;;7541:51;;;;-1:-1:-1;;;7541:51:9;;35660:2:21;7541:51:9;;;35642:21:21;35699:2;35679:18;;;35672:30;-1:-1:-1;;;35718:18:21;;;35711:48;35776:18;;7541:51:9;35458:342:21;7541:51:9;7636:6;7643:1;7636:9;;;;;;;;:::i;:::-;;;;;;;7626:7;:19;;;;:::i;:::-;-1:-1:-1;;;;;7606:17:9;;;;;;:8;:17;;;;;:39;;;;7678:7;;:4;;7683:1;;7678:7;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;7678:12:9;7698:6;7705:1;7698:9;;;;;;;;:::i;:::-;;;;;;;7678:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7659:53;;;7734:7;7726:36;;;;-1:-1:-1;;;7726:36:9;;36007:2:21;7726:36:9;;;35989:21:21;36046:2;36026:18;;;36019:30;-1:-1:-1;;;36065:18:21;;;36058:46;36121:18;;7726:36:9;35805:340:21;7726:36:9;7800:4;7805:1;7800:7;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;7781:38:9;7791:7;-1:-1:-1;;;;;7781:38:9;;7809:6;7816:1;7809:9;;;;;;;;:::i;:::-;;;;;;;7781:38;;;;24322:25:21;;24310:2;24295:18;;24176:177;7781:38:9;;;;;;;;7478:352;;7473:3;;;;;:::i;:::-;;;;7434:396;;;;7369:467;7271:565;;:::o;16511:4108::-;16819:15;16836:12;16864:30;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16864:30:9;16926:18;:16;:18::i;:::-;16904:40;;16998:9;16980:27;;:15;:27;:::i;:::-;16954:23;;;:53;17435:10;17457:4;17435:27;17427:66;;;;-1:-1:-1;;;17427:66:9;;31065:2:21;17427:66:9;;;31047:21:21;31104:2;31084:18;;;31077:30;31143:28;31123:18;;;31116:56;31189:18;;17427:66:9;30863:350:21;17427:66:9;17913:8;:42;17922:22;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;17913:42:9;;;;;;;;;;;;;;-1:-1:-1;17913:42:9;;17892:18;;;:63;18097:147;-1:-1:-1;;;18133:34:9;18097:147;;18181:12;;18195:9;;;;18206:12;;;;18220:14;;18097:147;;;:::i;:::-;;;;-1:-1:-1;;18097:147:9;;;;;;;;;;;;;;;-1:-1:-1;;;;;18097:147:9;-1:-1:-1;;;;;;18097:147:9;;;;;;;;;;18085:9;;;:159;-1:-1:-1;;18294:20:9;;18349:22;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;18349:37:9;18391:16;:39;;;18432:4;:9;;;18349:93;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18328:114:9;;-1:-1:-1;18328:114:9;-1:-1:-1;18328:114:9;18456:169;;18488:41;18521:7;18488:32;:41::i;:::-;18547:63;18564:36;18602:7;18547:16;:63::i;:::-;18705:7;18694:33;;;;;;;;;;;;:::i;:::-;18638:89;;18662:28;;;18638:89;18639:21;;;18638:89;-1:-1:-1;;;;18993:49:9;19018:12;19032:9;;18993:24;:49::i;:::-;18962:27;;;18918:124;;;18937:23;;;18918:124;;-1:-1:-1;18918:124:9;19056:140;;19099:82;19116:35;19153:4;:27;;;19099:16;:82::i;:::-;19214:4;:28;;;:56;;;;;19247:4;:23;;;19246:24;19214:56;19210:247;;;19354:88;19371:41;19414:4;:27;;;19354:16;:88::i;:::-;18869:598;19777:35;;;19826:4;:21;;;19861:4;:23;;;19947:18;:16;:18::i;:::-;19925:19;;:40;;;;:::i;:::-;19898:4;:23;;;:68;;;;:::i;:::-;20002:12;:22;;;;;;;;:::i;:::-;19741:293;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;19741:293:9;;;;;;;;;;;;;;;-1:-1:-1;;;;;19741:293:9;-1:-1:-1;;;;;;19741:293:9;;;;;;;;;;19729:9;;;:305;-1:-1:-1;;;;20093:22:9;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;20093:37:9;20135:16;:40;;;20177:4;:9;;;20093:94;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20055:132;;;;20207:11;20202:107;;20238:56;20255:33;20290:3;20238:16;:56::i;:::-;-1:-1:-1;;20378:18:9;;;;20333:8;:42;20342:22;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;20333:42:9;-1:-1:-1;;;;;20333:42:9;;;;;;;;;;;;;:63;20329:155;;;20412:61;20429:39;20412:61;;;;;;;;;;;;:16;:61::i;:::-;20502:4;:23;;;:80;;20549:33;20502:80;;;20528:18;20502:80;20584:4;:27;;;20494:118;;;;;16511:4108;;;;;;;;;;;:::o;2352:404::-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;2492:12:9::1;:19;2476:5;:12;:35;2468:78;;;::::0;-1:-1:-1;;;2468:78:9;;32487:2:21;2468:78:9::1;::::0;::::1;32469:21:21::0;32526:2;32506:18;;;32499:30;32565:32;32545:18;;;32538:60;32615:18;;2468:78:9::1;32285:354:21::0;2468:78:9::1;2561:9;2556:194;2580:5;:12;2576:1;:16;2556:194;;;2646:12;2659:1;2646:15;;;;;;;;:::i;:::-;;;;;;;2613:20;:30;2634:5;2640:1;2634:8;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;2613:30:9::1;-1:-1:-1::0;;;;;2613:30:9::1;;;;;;;;;;;;:48;;;;2680:59;2712:5;2718:1;2712:8;;;;;;;;:::i;:::-;;;;;;;2723:12;2736:1;2723:15;;;;;;;;:::i;:::-;;;;;;;2680:59;;;;;;-1:-1:-1::0;;;;;22201:32:21;;;;22183:51;;22265:2;22250:18;;22243:34;22171:2;22156:18;;22009:274;2680:59:9::1;;;;;;;;2594:3:::0;::::1;::::0;::::1;:::i;:::-;;;;2556:194;;;;2352:404:::0;;:::o;21141:281::-;21245:13;;21223:7;;-1:-1:-1;;;21245:13:9;;;;21241:100;;-1:-1:-1;21329:1:9;;21141:281;-1:-1:-1;21141:281:9:o;21241:100::-;21386:13;;21402:3;;-1:-1:-1;;;21386:13:9;;;;21377:22;;:28;;21141:281;-1:-1:-1;;21141:281:9:o;21458:561::-;21577:7;;21625:22;;21651:30;;;;21625:56;21621:152;;;-1:-1:-1;21707:1:9;21621:152;;;-1:-1:-1;21749:13:9;21621:152;21782:26;21811:97;21820:22;;21844:63;21853:11;21844:63;21876:30;;;;21866:7;:40;:::i;:::-;21844:8;:63::i;21811:97::-;21980:18;;21782:126;;-1:-1:-1;22009:3:9;;21980:24;;:18;;22009:3;21980:24;:::i;:::-;21948:57;;:28;21958:18;21948:7;:28;:::i;:::-;:57;;;;:::i;:::-;21947:65;;;;:::i;:::-;21925:19;;:87;;;-1:-1:-1;;;21925:19:9;;-1:-1:-1;;;;;21925:19:9;:87;:::i;:::-;21918:94;21458:561;-1:-1:-1;;;;;21458:561:9:o;1978:216::-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;2096:3:9::1;2079:7;:14;;;:20;;;2071:49;;;::::0;-1:-1:-1;;;2071:49:9;;37757:2:21;2071:49:9::1;::::0;::::1;37739:21:21::0;37796:2;37776:18;;;37769:30;-1:-1:-1;;;37815:18:21;;;37808:46;37871:18;;2071:49:9::1;37555:340:21::0;2071:49:9::1;2130:16:::0;;:6:::1;:16:::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;-1:-1:-1;;;;;2130:16:9::1;-1:-1:-1::0;;;2130:16:9::1;-1:-1:-1::0;;;;2130:16:9::1;::::0;;::::1;-1:-1:-1::0;;;2130:16:9::1;-1:-1:-1::0;;;;;;2130:16:9;;;-1:-1:-1;;;;;2130:16:9;;::::1;::::0;;;;;;;::::1;;::::0;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;-1:-1:-1::0;;2130:16:9;;::::1;::::0;;;::::1;::::0;;2161:26;::::1;::::0;::::1;::::0;40894:13:21;;40876:32;;40964:4;40952:17;;40946:24;40939:4;40924:20;;40917:54;41027:4;41015:17;;41009:24;41002:4;40987:20;;40980:54;41090:4;41078:17;;41072:24;41065:4;41050:20;;41043:54;41153:4;41141:17;;41135:24;41128:4;41113:20;;41106:54;41204:4;41192:17;;41186:24;-1:-1:-1;;;;;41238:35:21;;41290:4;41275:20;;;14168:44;;;;41348:4;41326:20;;;;41322:31;41370:4;41355:20;;17881:29;-1:-1:-1;;;;;41411:3:21;41407:19;;;;41403:48;41468:4;41453:20;;17779:47;41563:4;41551:17;;;41545:24;47673:6;47657:23;41626:6;41611:22;;17684:31;40863:3;40848:19;;40668:972;2161:26:9::1;;;;;;;;1978:216:::0;:::o;6403:328::-;6489:54;-1:-1:-1;;;;;6489:24:9;;-1:-1:-1;;;6489:24:9;:54::i;:::-;6481:99;;;;-1:-1:-1;;;6481:99:9;;27466:2:21;6481:99:9;;;27448:21:21;;;27485:18;;;27478:30;27544:34;27524:18;;;27517:62;27596:18;;6481:99:9;27264:356:21;6481:99:9;-1:-1:-1;;;;;6646:16:9;;6590:14;6646:16;;;:8;:16;;;;;;6607:9;;6646:25;;6607:9;;6646:25;:::i;:::-;-1:-1:-1;;;;;6627:16:9;;;;;;:8;:16;;;;;;;;;:44;;;;6687:37;24322:25:21;;;6705:10:9;;6687:37;;24295:18:21;6687:37:9;;;;;;;6471:260;6403:328;:::o;22810:226::-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;23168:15:9;;23149;:34;22894:46:::1;;;::::0;-1:-1:-1;;;22894:46:9;;28889:2:21;22894:46:9::1;::::0;::::1;28871:21:21::0;28928:2;28908:18;;;28901:30;-1:-1:-1;;;28947:18:21;;;28940:48;29005:18;;22894:46:9::1;28687:342:21::0;22894:46:9::1;22950:15;:34:::0;;;22999:30:::1;::::0;24322:25:21;;;22999:30:9::1;::::0;24310:2:21;24295:18;22999:30:9::1;24176:177:21::0;9652:6357:9;9886:22;9918:14;9942:32;9984:24;10024:25;;:::i;:::-;10081:18;:16;:18::i;:::-;10059:19;;;:40;10131:51;10158:12;10172:9;;10131:26;:51::i;:::-;10109:19;;;:73;23168:15;;23149;:34;10193:42;;;;-1:-1:-1;;;10193:42:9;;28188:2:21;10193:42:9;;;28170:21:21;28227:2;28207:18;;;28200:30;-1:-1:-1;;;28246:18:21;;;28239:44;28300:18;;10193:42:9;27986:338:21;10193:42:9;10303:1;10269:20;:12;;:20;:::i;:::-;:25;;;;;;;:::i;:::-;:32;;:35;;:102;;10369:1;10269:102;;;10307:52;10330:20;:12;;:20;:::i;:::-;:25;;;;;;;:::i;:::-;10307:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10307:52:9;-1:-1:-1;10307:22:9;;-1:-1:-1;;10307:52:9:i;:::-;-1:-1:-1;;;;;;10245:126:9;:21;;;:126;10386:10;-1:-1:-1;;;;;10400:12:9;10386:26;;;;;:58;;-1:-1:-1;10416:9:9;:28;;10386:58;10382:322;;;10468:21;10460:66;;;;-1:-1:-1;;;10460:66:9;;32126:2:21;10460:66:9;;;32108:21:21;;;32145:18;;;32138:30;32204:34;32184:18;;;32177:62;32256:18;;10460:66:9;31924:356:21;10460:66:9;10548:10;10562:9;10548:23;10540:60;;;;-1:-1:-1;;;10540:60:9;;31773:2:21;10540:60:9;;;31755:21:21;31812:2;31792:18;;;31785:30;31851:26;31831:18;;;31824:54;31895:18;;10540:60:9;31571:348:21;10540:60:9;10636:22;;;;:12;:22;:::i;:::-;:34;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;10622:48:9;:10;-1:-1:-1;;;;;10622:48:9;;10614:79;;;;-1:-1:-1;;;10614:79:9;;37056:2:21;10614:79:9;;;37038:21:21;37095:2;37075:18;;;37068:30;-1:-1:-1;;;37114:18:21;;;37107:48;37172:18;;10614:79:9;36854:342:21;10614:79:9;10718:9;:28;10714:265;;10782:15;:51;10798:22;;;;:12;:22;:::i;:::-;:34;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;10782:51:9;;;;;;;;;;;;;;-1:-1:-1;10782:51:9;;;10762:17;;;:71;;;10847:64;;;;-1:-1:-1;;;10847:64:9;;38810:2:21;10847:64:9;;;38792:21:21;38849:2;38829:18;;;38822:30;-1:-1:-1;;;38868:18:21;;;38861:50;38928:18;;10847:64:9;38608:344:21;10847:64:9;10925:43;10950:4;:17;;;10925:24;:43::i;:::-;11048:78;11071:19;11092:12;11106:4;:19;;;11048:22;:78::i;:::-;11013:19;;;10989:137;10990:21;;;10989:137;11137:79;11180:12;11193:9;;11203:12;;11137:42;:79::i;:::-;11442:17;;11438:2;11425:9;:12;;11435:2;11425:12;:::i;:::-;:15;;;;:::i;:::-;:34;;;;:::i;:::-;11404:18;;;:55;11491:18;:16;:18::i;:::-;11469:4;:19;;:40;;;;;12306:22;12447:6;:19;;;12426:6;:18;;;12405:4;:18;;;12383:4;:19;;;12331:12;:22;;;;;;;;:::i;:::-;:49;;;:71;;;;:::i;:::-;:92;;;;:::i;:::-;:113;;;;:::i;:::-;:135;;;;:::i;:::-;12306:160;;12735:12;12749:28;12789:4;-1:-1:-1;;;;;12781:18:9;12804:4;:18;;;12860:32;;;12894:12;12908:9;;12919:12;;12933:4;:21;;;12985:18;:16;:18::i;:::-;12968:35;;:14;:35;:::i;:::-;13039:4;:19;;;12837:235;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;12837:235:9;;;;;;;;;;;;;;-1:-1:-1;;;;;12837:235:9;-1:-1:-1;;;;;;12837:235:9;;;;;;;;;;12781:301;;;;12837:235;12781:301;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13092:22:9;;;;;12734:348;;-1:-1:-1;12734:348:9;-1:-1:-1;13164:18:9;:16;:18::i;:::-;13144:4;:19;;;:38;;;;:::i;:::-;13124:17;;;:58;13237:53;;;;;;;;;;;;;;:::i;:::-;13193:4;:11;;13206:4;:27;;13192:98;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;-1:-1:-1;;13305:27:9;;;;:34;:36;13300:133;;13363:59;13381:4;:11;;;13394:4;:27;;;13363:59;;;;;;;:::i;:::-;;;;;;;;13300:133;-1:-1:-1;;13459:12:9;;;-1:-1:-1;13454:1054:9;;13559:36;13544:4;:11;;;:51;;;;;;;;:::i;:::-;;:417;;;-1:-1:-1;13682:22:9;;;;:12;:22;:::i;:::-;13641:21;;;;:38;:90;;13682:49;;;;13641:90;:::i;:::-;13620:4;:17;;;:111;;13619:342;;;;-1:-1:-1;13773:35:9;13758:4;:11;;;:50;;;;;;;;:::i;:::-;;:130;;;-1:-1:-1;13847:41:9;13832:4;:11;;;:56;;;;;;;;:::i;:::-;;13758:130;13540:958;;;14131:19;;;;14077:22;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;14038:17;;;;-1:-1:-1;;;;;13986:420:9;;;;;;14172:20;:12;;:20;:::i;:::-;:25;;;;;;;:::i;:::-;14219:20;:12;;:20;:::i;:::-;:23;;;;;;;;;:::i;:::-;14264:10;14296:4;:21;;;14339:4;:17;;;14378:4;:27;;;13986:420;;;;;;;;;;;:::i;:::-;;;;;;;;14432:5;14439:1;14442:4;:11;;;14455:4;:27;;;14424:59;;;;;;;;;;;13540:958;14718:18;;14696;:16;:18::i;:::-;14674:4;:19;;;:40;;;;:::i;:::-;14621:22;;;;:12;:22;:::i;:::-;:49;;;:94;;;;:::i;:::-;:115;;;;:::i;:::-;14606:12;;;:130;;;14755:53;;14785:22;;;;:12;:22;:::i;14755:53::-;14746:62;;14835:26;14854:6;14835:18;:26::i;:::-;14818:14;;;:43;14962:6;14917:8;:42;14926:22;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14917:42:9;-1:-1:-1;;;;;14917:42:9;;;;;;;;;;;;;:51;;;;:::i;:::-;14872:8;:42;14881:22;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14872:42:9;;;;;;;;;;;;-1:-1:-1;14872:42:9;:96;15048:14;;;;15039:23;;:6;:23;:::i;:::-;15017:17;;;;-1:-1:-1;;;;;15008:27:9;;;;;:8;:27;;;;;;:55;;;;:::i;:::-;14987:17;;;;-1:-1:-1;;;;;14978:27:9;;;;;:8;:27;;;;;:85;15077:14;;;;:18;15073:167;;15215:14;;;;15194:17;;-1:-1:-1;;;;;15194:17:9;15185:27;;;;:8;:27;;;;;;:44;;15215:14;15185:44;:::i;:::-;15164:17;;-1:-1:-1;;;;;15164:17:9;15155:27;;;;:8;:27;;;;;:74;15073:167;15264:12;15279:20;:12;;:20;:::i;:::-;:25;;;;;;;:::i;:::-;15264:40;-1:-1:-1;15318:10:9;15331:20;:12;;:20;:::i;:::-;:23;;;;;;;;;:::i;:::-;15318:36;-1:-1:-1;15368:17:9;15388:22;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;15368:52;;15538:4;:19;;;15510:10;-1:-1:-1;;;;;15439:280:9;15475:4;:17;;;-1:-1:-1;;;;;15439:280:9;;15575:4;15597:2;15617:9;15644:4;:21;;;15683:4;:11;;;15712:6;15439:280;;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;15831:9:9;15827:122;;15897:11;;;;15910:27;;;;;15883:4;;-1:-1:-1;15897:11:9;;-1:-1:-1;15910:27:9;-1:-1:-1;15875:63:9;;15827:122;15980:11;;;15958:38;;;;;;;;;-1:-1:-1;15958:38:9;;15966:4;;-1:-1:-1;15980:11:9;;-1:-1:-1;15958:38:9;-1:-1:-1;9652:6357:9;;;;;;;;;;;;:::o;5655:712::-;5767:10;5744:20;5812:25;;;:11;:25;;;;;;:50;;5840:15;;5812:50;:::i;:::-;-1:-1:-1;;;;;5872:25:9;;;;;;:11;:25;;;;;:42;;;5950:6;:21;5787:75;;-1:-1:-1;5932:39:9;;;5924:68;;;;-1:-1:-1;;;5924:68:9;;34960:2:21;5924:68:9;;;34942:21:21;34999:2;34979:18;;;34972:30;-1:-1:-1;;;35018:18:21;;;35011:46;35074:18;;5924:68:9;34758:340:21;5924:68:9;6003:38;6028:12;6003:24;:38::i;:::-;6057:9;6052:229;6072:26;;;6052:229;;;6174:1;6127:15;6174:1;6143:15;;6159:1;6143:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;6127:35:9;;;;;;;;;;;;;;-1:-1:-1;6127:35:9;;;:49;6119:87;;;;-1:-1:-1;;;6119:87:9;;29236:2:21;6119:87:9;;;29218:21:21;29275:2;29255:18;;;29248:30;29314:27;29294:18;;;29287:55;29359:18;;6119:87:9;29034:349:21;6119:87:9;6258:12;6220:15;:35;6236:15;;6252:1;6236:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;6220:35:9;;;;;;;;;;;;;;-1:-1:-1;6220:35:9;:50;;-1:-1:-1;;;;;;6220:50:9;;;;;;;;;;;6100:3;;;;:::i;:::-;;;;6052:229;;;;6314:12;-1:-1:-1;;;;;6296:64:9;;6328:15;;6345:14;6296:64;;;;;;;;:::i;:::-;;;;;;;;5734:633;;5655:712;;:::o;24210:433::-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;24316:45:9::1;::::0;-1:-1:-1;;;24316:45:9;;-1:-1:-1;;;;;20233:32:21;;;24316:45:9::1;::::0;::::1;20215:51:21::0;24316:12:9::1;:31;::::0;::::1;::::0;20188:18:21;;24316:45:9::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24308:90;;;::::0;-1:-1:-1;;;24308:90:9;;30350:2:21;24308:90:9::1;::::0;::::1;30332:21:21::0;;;30369:18;;;30362:30;30428:34;30408:18;;;30401:62;30480:18;;24308:90:9::1;30148:356:21::0;24308:90:9::1;-1:-1:-1::0;;;;;24426:22:9;;::::1;24408:15;24426:22:::0;;;:8:::1;:22;::::0;;;;;;;24458:26;;;;24533:17;;;;::::1;24524:27:::0;;;;;:37:::1;::::0;24426:22;;24524:37:::1;:::i;:::-;24503:17:::0;;-1:-1:-1;;;;;24503:17:9;;::::1;24494:27;::::0;;;:8:::1;:27;::::0;;;;;;;;:67;;;;24576:60;24322:25:21;;;24576:60:9;;::::1;::::0;::::1;::::0;24295:18:21;24576:60:9::1;;;;;;;24298:345;24210:433:::0;:::o;1438:134::-;1498:13;1522:43;;;;;;;;;;;;;;;;;;;1438:134;:::o;22055:719::-;22204:39;;-1:-1:-1;;;22204:39:9;;-1:-1:-1;;;;;20233:32:21;;;22204:39:9;;;20215:51:21;22143:35:9;;;;22204:12;:25;;;;20188:18:21;;22204:39:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22297:10;;;;;-1:-1:-1;;;;;22276:32:9;;;22253:20;22276:32;;;:20;:32;;;;;;22326:10;;22142:101;;-1:-1:-1;22142:101:9;;-1:-1:-1;22276:32:9;22326;22318:69;;;;-1:-1:-1;;;22318:69:9;;31420:2:21;22318:69:9;;;31402:21:21;31459:2;31439:18;;;31432:30;-1:-1:-1;;;31478:18:21;;;31471:54;31542:18;;22318:69:9;31218:348:21;22318:69:9;22405:10;;:26;-1:-1:-1;22405:26:9;22397:64;;;;-1:-1:-1;;;22397:64:9;;32846:2:21;22397:64:9;;;32828:21:21;32885:2;32865:18;;;32858:30;32924:27;32904:18;;;32897:55;32969:18;;22397:64:9;32644:349:21;22397:64:9;22479:17;22471:61;;;;-1:-1:-1;;;22471:61:9;;34600:2:21;22471:61:9;;;34582:21:21;34639:2;34619:18;;;34612:30;34678:33;34658:18;;;34651:61;34729:18;;22471:61:9;34398:355:21;22471:61:9;22571:26;;22550:17;;;;:47;;22542:86;;;;-1:-1:-1;;;22542:86:9;;36701:2:21;22542:86:9;;;36683:21:21;36740:2;36720:18;;;36713:30;36779:28;36759:18;;;36752:56;36825:18;;22542:86:9;36499:350:21;22542:86:9;22646:17;;;;:22;22638:59;;;;-1:-1:-1;;;22638:59:9;;29590:2:21;22638:59:9;;;29572:21:21;29629:2;29609:18;;;29602:30;29668:26;29648:18;;;29641:54;29712:18;;22638:59:9;29388:348:21;22638:59:9;22715:15;22707:60;;;;-1:-1:-1;;;22707:60:9;;27827:2:21;22707:60:9;;;27809:21:21;;;27846:18;;;27839:30;27905:34;27885:18;;;27878:62;27957:18;;22707:60:9;27625:356:21;23425:559:9;23330:10;-1:-1:-1;;;;;23344:9:9;23330:23;;23322:49;;;;-1:-1:-1;;;23322:49:9;;33897:2:21;23322:49:9;;;33879:21:21;33936:2;33916:18;;;33909:30;-1:-1:-1;;;33955:18:21;;;33948:43;34008:18;;23322:49:9;33695:337:21;23322:49:9;-1:-1:-1;;;;;23558:28:9;;::::1;23535:20;23558:28:::0;;;:15:::1;:28;::::0;;;;;::::1;23678:26:::0;23670:59:::1;;;::::0;-1:-1:-1;;;23670:59:9;;38810:2:21;23670:59:9::1;::::0;::::1;38792:21:21::0;38849:2;38829:18;;;38822:30;-1:-1:-1;;;38868:18:21;;;38861:50;38928:18;;23670:59:9::1;38608:344:21::0;23670:59:9::1;23785:39;::::0;-1:-1:-1;;;23785:39:9;;-1:-1:-1;;;;;20233:32:21;;;23785:39:9::1;::::0;::::1;20215:51:21::0;23740:40:9::1;::::0;23785:12:::1;:25:::0;;::::1;::::0;::::1;::::0;20188:18:21;;23785:39:9::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;23842:15:9;;23739:85;;-1:-1:-1;23834:56:9::1;;;::::0;-1:-1:-1;;;23834:56:9;;31420:2:21;23834:56:9::1;::::0;::::1;31402:21:21::0;31459:2;31439:18;;;31432:30;-1:-1:-1;;;31478:18:21;;;31471:54;31542:18;;23834:56:9::1;31218:348:21::0;23834:56:9::1;23961:15:::0;;23900:77:::1;::::0;-1:-1:-1;;;23900:77:9;;-1:-1:-1;;;;;20543:15:21;;;23900:77:9::1;::::0;::::1;20525:34:21::0;20595:15;;;20575:18;;;20568:43;20627:18;;;20620:34;;;;23900:12:9::1;:33:::0;;::::1;::::0;::::1;::::0;20460:18:21;;23900:77:9::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;23525:459;;23425:559:::0;;:::o;1918:198:0:-;1082:7;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;2006:22:0;::::1;1998:73;;;::::0;-1:-1:-1;;;1998:73:0;;29943:2:21;1998:73:0::1;::::0;::::1;29925:21:21::0;29982:2;29962:18;;;29955:30;30021:34;30001:18;;;29994:62;-1:-1:-1;;;30072:18:21;;;30065:36;30118:19;;1998:73:0::1;29741:402:21::0;1998:73:0::1;2081:28;2100:8;2081:18;:28::i;:::-;1918:198:::0;:::o;6919:316:9:-;7028:16;;;7042:1;7028:16;;;;;;;;;7001:24;;7028:16;;;;;;;;;-1:-1:-1;;7094:24:9;;;7116:1;7094:24;;;;;;;;;7001:43;;-1:-1:-1;7054:37:9;;7094:24;-1:-1:-1;7094:24:9;;;;;;;;;;;-1:-1:-1;7094:24:9;7054:64;;7141:6;7128:7;7136:1;7128:10;;;;;;;;:::i;:::-;;;;;;:19;;;;;7175:4;7157:12;7170:1;7157:15;;;;;;;;:::i;:::-;;;;;;:22;-1:-1:-1;;;;;7157:22:9;;;-1:-1:-1;;;;;7157:22:9;;;;;7189:39;7206:12;7220:7;7189:16;:39::i;2270:187:0:-;2343:16;2362:6;;-1:-1:-1;;;;;2378:17:0;;;-1:-1:-1;;;;;;2378:17:0;;;;;;2410:40;;2362:6;;;;;;;2410:40;;2343:16;2410:40;2333:124;2270:187;:::o;4425:125:16:-;4493:50;4521:4;563;4493:27;:50::i;20766:339:9:-;20857:17;20888:6;20896:3;20877:23;;;;;;;;;:::i;:::-;;;;;;;;;;;;;20857:43;;20910:38;20943:4;20910:32;:38::i;:::-;21004:4;20998:11;21047:2;21041:4;21037:13;21080:8;21071:7;21064:25;3386:813:16;3492:21;3515:16;3533;3562:23;3589:26;3602:12;3589;:26::i;:::-;3561:54;-1:-1:-1;3625:24:16;3652:49;3668:22;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;3652:15;:49::i;:::-;3625:76;-1:-1:-1;3799:22:16;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;3799:37:16;-1:-1:-1;;;3914:20:16;:12;;:20;:::i;:::-;3936:16;1295:18;;;;;;;;;;;;;-1:-1:-1;;;1295:18:16;;;1318:14;;;;;;;;;;;;;;;;;1203;;;;;;;;;;;;;;;;;1162:56;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1162:56:16;;;;;;;;;;1269:90;;;;1162:56;1269:90;;:::i;:::-;;;;;;;;;;;;;1491:29;;;;;;3978:10;3990:9;;3850:159;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;3850:159:16;;;;;;;;;;;;;;-1:-1:-1;;;;;3850:159:16;-1:-1:-1;;;;;;3850:159:16;;;;;;;;;;3799:211;;;;3850:159;3799:211;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3773:237:16;;-1:-1:-1;3773:237:16;-1:-1:-1;4020:143:16;;;;4133:3;4122:30;;;;;;;;;;;;:::i;:::-;4101:51;;-1:-1:-1;4101:51:16;-1:-1:-1;4020:143:16;4172:20;4188:3;4172:15;:20::i;:::-;3551:648;;3386:813;;;;;;;:::o;461:104:8:-;519:7;549:1;545;:5;:13;;557:1;545:13;;;553:1;545:13;538:20;461:104;-1:-1:-1;;;461:104:8:o;1318:274:6:-;1405:4;1512:23;1527:7;1512:14;:23::i;:::-;:73;;;;;1539:46;1564:7;1573:11;1539:24;:46::i;922:277:18:-;1055:7;-1:-1:-1;;;;;1102:20:18;:12;;:20;:::i;:::-;:25;;;;;;;:::i;:::-;1129:20;:12;;:20;:::i;:::-;:26;;;1157:9;;1091:76;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1081:87;;;;;;:111;1074:118;;922:277;;;;;:::o;2483:571:19:-;2603:13;2652:9;:5;2660:1;2652:9;:::i;:::-;2640:1;:8;:21;;2632:60;;;;-1:-1:-1;;;2632:60:19;;38455:2:21;2632:60:19;;;38437:21:21;38494:2;38474:18;;;38467:30;38533:28;38513:18;;;38506:56;38579:18;;2632:60:19;38253:350:21;2632:60:19;-1:-1:-1;2787:21:19;2804:2;2787:21;2781:28;-1:-1:-1;;;;;;2936:79:19;;2483:571::o;7842:1235:9:-;8036:51;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8036:51:9;8089:22;8165;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;8154:64:9;;8223:5;8154:77;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8268:34;;;;8123:108;;-1:-1:-1;8249:8:9;:53;;8241:90;;;;-1:-1:-1;;;8241:90:9;;33545:2:21;8241:90:9;;;33527:21:21;33584:2;33564:18;;;33557:30;33623:25;33603:18;;;33596:53;33666:18;;8241:90:9;33343:347:21;8241:90:9;8373:33;;8350:56;;;8342:95;;;;-1:-1:-1;;;8342:95:9;;35305:2:21;8342:95:9;;;35287:21:21;35344:2;35324:18;;;35317:30;35383:28;35363:18;;;35356:56;35429:18;;8342:95:9;35103:350:21;8342:95:9;8492:39;;;;8455:33;;:76;;8447:114;;;;-1:-1:-1;;;8447:114:9;;30711:2:21;8447:114:9;;;30693:21:21;30750:2;30730:18;;;30723:30;30789:27;30769:18;;;30762:55;30834:18;;8447:114:9;30509:349:21;8447:114:9;8641:14;8589:22;;;;:12;:22;:::i;:::-;:49;;;:66;;;;:::i;:::-;8572:83;-1:-1:-1;8666:25:9;8694:89;8572:83;8751:22;;;;:12;:22;:::i;8694:89::-;8666:117;-1:-1:-1;8986:8:9;:42;8995:22;;;;:12;:22;:::i;:::-;:32;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;8986:42:9;-1:-1:-1;;;;;8986:42:9;;;;;;;;;;;;;8965:17;:63;;8957:113;;;;-1:-1:-1;;;8957:113:9;;37403:2:21;8957:113:9;;;37385:21:21;37442:2;37422:18;;;37415:30;37481:27;37461:18;;;37454:55;37526:18;;8957:113:9;37201:349:21;8957:113:9;8113:964;7842:1235;;;;;;:::o;510:1210:20:-;1236:26;1436:54;1453:22;;;;:12;:22;:::i;:::-;:36;;;;;;;:::i;:::-;1436:16;:54::i;:::-;1378:43;1395:20;:12;;:20;:::i;:::-;:25;;;;;;;:::i;1378:43::-;1333:30;1350:12;;1333:16;:30::i;:::-;1291:27;1308:9;;1291:16;:27::i;:::-;1265:53;;:11;:53;:::i;:::-;:98;;;;:::i;:::-;:156;;;;:::i;:::-;:225;;;;:::i;:::-;1236:254;-1:-1:-1;1601:2:20;1581:22;;;1573:59;;;;-1:-1:-1;;;1573:59:20;;38102:2:21;1573:59:20;;;38084:21:21;38141:2;38121:18;;;38114:30;38180:26;38160:18;;;38153:54;38224:18;;1573:59:20;37900:348:21;1573:59:20;1672:8;1650:37;;1642:71;;;;-1:-1:-1;;;1642:71:20;;36352:2:21;1642:71:20;;;36334:21:21;36391:2;36371:18;;;36364:30;-1:-1:-1;;;36410:18:21;;;36403:50;36470:18;;1642:71:20;36150:344:21;1642:71:20;688:1032;510:1210;;;;;:::o;429:173:19:-;531:6;517:4;:11;:20;513:83;;;577:6;571:4;564:20;513:83;429:173;;:::o;1829:229:16:-;1945:23;2022:28;2036:13;;;;:3;:13;:::i;:::-;2022;:28::i;:::-;1998:53;;;;;;24322:25:21;;24310:2;24295:18;;24176:177;1998:53:16;;;;;;;;;;;;;1985:66;;1829:229;;;:::o;4556:292::-;4660:180;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;4660:180:16;;;;;;;;;;;-1:-1:-1;;4649:192:16;;4660:180;-1:-1:-1;;4999:9:16;4660:180;;;;4816:9;-1:-1:-1;;;;;4660:180:16;;;;4649:10;:192::i;689:411:6:-;753:4;960:60;985:7;-1:-1:-1;;;960:24:6;:60::i;:::-;:133;;;;-1:-1:-1;1037:56:6;1062:7;-1:-1:-1;;;;;;1037:24:6;:56::i;:::-;1036:57;941:152;689:411;-1:-1:-1;;689:411:6:o;4208:409::-;4346:71;;;-1:-1:-1;;;;;;25835:33:21;;4346:71:6;;;;25817:52:21;;;;4346:71:6;;;;;;;;;;25790:18:21;;;;4346:71:6;;;;;;;-1:-1:-1;;;;;4346:71:6;-1:-1:-1;;;4346:71:6;;;4465:45;;4301:4;;4346:71;4301:4;;;;-1:-1:-1;;;;;4465:18:6;;;4489:5;;4465:45;;4346:71;;4465:45;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4427:83;;;;4540:2;4524:6;:13;:18;4520:36;;;4551:5;4544:12;;;;;;;4520:36;4573:7;:37;;;;;4595:6;4584:26;;;;;;;;;;;;:::i;:::-;4566:44;4208:409;-1:-1:-1;;;;;;4208:409:6:o;1934:153:20:-;2003:7;2056:22;2076:2;-1:-1:-1;;2056:22:20;:::i;:::-;2036:15;:3;2049:2;2036:15;:::i;:::-;2029:51;;2035:44;2029:2;:51;:::i;5357:478:16:-;5436:7;1421:14;;;;;;;;;;;;;;;;;1411:25;;;;;;;;5536:16;;;5570:24;;;5612:30;;;;5660:15;;;;;;;;:::i;:::-;5693:13;;;;;;;;:::i;:::-;5724;;;;;;;;:::i;:::-;5765:17;;;;:3;:17;:::i;:::-;5755:28;;;;;;;:::i;:::-;;;;;;;;;5472:355;;;;;;;;;5801:12;;;;;5472:355;;25223:25:21;;;25279:2;25264:18;;25257:34;;;;25322:2;25307:18;;25300:34;;;;25365:2;25350:18;;25343:34;;;;-1:-1:-1;;;;;25452:15:21;;;25446:3;25431:19;;25424:44;25505:15;;25404:3;25484:19;;25477:44;25558:15;25552:3;25537:19;;25530:44;25605:3;25590:19;;25583:35;25649:3;25634:19;;25627:35;25210:3;25195:19;;24852:816;5472:355:16;;;;;;;;;;;;;5462:366;;;;;;5455:373;;5357:478;;;:::o;5030:321::-;5098:7;1713:109;5217:3;:8;;;5201:26;;;;;;5261:3;:11;;;5245:29;;;;;;5292:3;:11;;;5321:3;:21;;;5134:209;;;;;;;;;;;24617:25:21;;;24673:2;24658:18;;24651:34;;;;24716:2;24701:18;;24694:34;;;;24759:2;24744:18;;24737:34;-1:-1:-1;;;;;24808:32:21;24802:3;24787:19;;24780:61;24604:3;24589:19;;24358:489;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:134:21:-;82:20;;111:31;82:20;111:31;:::i;:::-;14:134;;;:::o;153:681::-;207:5;260:3;253:4;245:6;241:17;237:27;227:55;;278:1;275;268:12;227:55;314:6;301:20;340:4;364:68;380:51;428:2;380:51;:::i;:::-;364:68;:::i;:::-;454:3;478:2;473:3;466:15;506:2;501:3;497:12;490:19;;541:2;533:6;529:15;593:3;588:2;582;579:1;575:10;567:6;563:23;559:32;556:41;553:61;;;610:1;607;600:12;553:61;632:1;642:163;656:2;653:1;650:9;642:163;;;713:17;;701:30;;751:12;;;;783;;;;674:1;667:9;642:163;;;-1:-1:-1;823:5:21;;153:681;-1:-1:-1;;;;;;;153:681:21:o;839:164::-;915:13;;964;;957:21;947:32;;937:60;;993:1;990;983:12;1008:347;1059:8;1069:6;1123:3;1116:4;1108:6;1104:17;1100:27;1090:55;;1141:1;1138;1131:12;1090:55;-1:-1:-1;1164:20:21;;-1:-1:-1;;;;;1196:30:21;;1193:50;;;1239:1;1236;1229:12;1193:50;1276:4;1268:6;1264:17;1252:29;;1328:3;1321:4;1312:6;1304;1300:19;1296:30;1293:39;1290:59;;;1345:1;1342;1335:12;1290:59;1008:347;;;;;:::o;1360:496::-;1413:5;1466:3;1459:4;1451:6;1447:17;1443:27;1433:55;;1484:1;1481;1474:12;1433:55;1513:6;1507:13;-1:-1:-1;;;;;1535:2:21;1532:26;1529:52;;;1561:18;;:::i;:::-;1605:55;1648:2;1629:13;;-1:-1:-1;;1625:27:21;1654:4;1621:38;1605:55;:::i;:::-;1685:2;1676:7;1669:19;1731:3;1724:4;1719:2;1711:6;1707:15;1703:26;1700:35;1697:55;;;1748:1;1745;1738:12;1697:55;1761:64;1822:2;1815:4;1806:7;1802:18;1795:4;1787:6;1783:17;1761:64;:::i;:::-;1843:7;1360:496;-1:-1:-1;;;;1360:496:21:o;1861:160::-;1926:5;1971:2;1962:6;1957:3;1953:16;1949:25;1946:45;;;1987:1;1984;1977:12;1946:45;-1:-1:-1;2009:6:21;1861:160;-1:-1:-1;1861:160:21:o;2026:159::-;2093:20;;2153:6;2142:18;;2132:29;;2122:57;;2175:1;2172;2165:12;2190:156;2256:20;;2316:4;2305:16;;2295:27;;2285:55;;2336:1;2333;2326:12;2351:175;2418:20;;-1:-1:-1;;;;;2467:34:21;;2457:45;;2447:73;;2516:1;2513;2506:12;2531:247;2590:6;2643:2;2631:9;2622:7;2618:23;2614:32;2611:52;;;2659:1;2656;2649:12;2611:52;2698:9;2685:23;2717:31;2742:5;2717:31;:::i;2783:323::-;2859:6;2867;2920:2;2908:9;2899:7;2895:23;2891:32;2888:52;;;2936:1;2933;2926:12;2888:52;2975:9;2962:23;2994:31;3019:5;2994:31;:::i;:::-;3044:5;3096:2;3081:18;;;;3068:32;;-1:-1:-1;;;2783:323:21:o;3111:396::-;3187:6;3195;3248:2;3236:9;3227:7;3223:23;3219:32;3216:52;;;3264:1;3261;3254:12;3216:52;3303:9;3290:23;3322:31;3347:5;3322:31;:::i;:::-;3372:5;-1:-1:-1;3429:2:21;3414:18;;3401:32;3442:33;3401:32;3442:33;:::i;:::-;3494:7;3484:17;;;3111:396;;;;;:::o;3512:615::-;3598:6;3606;3659:2;3647:9;3638:7;3634:23;3630:32;3627:52;;;3675:1;3672;3665:12;3627:52;3715:9;3702:23;-1:-1:-1;;;;;3785:2:21;3777:6;3774:14;3771:34;;;3801:1;3798;3791:12;3771:34;3839:6;3828:9;3824:22;3814:32;;3884:7;3877:4;3873:2;3869:13;3865:27;3855:55;;3906:1;3903;3896:12;3855:55;3946:2;3933:16;3972:2;3964:6;3961:14;3958:34;;;3988:1;3985;3978:12;3958:34;4041:7;4036:2;4026:6;4023:1;4019:14;4015:2;4011:23;4007:32;4004:45;4001:65;;;4062:1;4059;4052:12;4001:65;4093:2;4085:11;;;;;4115:6;;-1:-1:-1;3512:615:21;;-1:-1:-1;;;;3512:615:21:o;4132:1242::-;4258:6;4266;4319:2;4307:9;4298:7;4294:23;4290:32;4287:52;;;4335:1;4332;4325:12;4287:52;4375:9;4362:23;-1:-1:-1;;;;;4445:2:21;4437:6;4434:14;4431:34;;;4461:1;4458;4451:12;4431:34;4499:6;4488:9;4484:22;4474:32;;4544:7;4537:4;4533:2;4529:13;4525:27;4515:55;;4566:1;4563;4556:12;4515:55;4602:2;4589:16;4624:4;4648:68;4664:51;4712:2;4664:51;:::i;4648:68::-;4738:3;4762:2;4757:3;4750:15;4790:2;4785:3;4781:12;4774:19;;4821:2;4817;4813:11;4869:7;4864:2;4858;4855:1;4851:10;4847:2;4843:19;4839:28;4836:41;4833:61;;;4890:1;4887;4880:12;4833:61;4912:1;4903:10;;4922:238;4936:2;4933:1;4930:9;4922:238;;;5007:3;4994:17;5024:31;5049:5;5024:31;:::i;:::-;5068:18;;4954:1;4947:9;;;;;5106:12;;;;5138;;4922:238;;;-1:-1:-1;5179:5:21;-1:-1:-1;;5222:18:21;;5209:32;;-1:-1:-1;;5253:16:21;;;5250:36;;;5282:1;5279;5272:12;5250:36;;5305:63;5360:7;5349:8;5338:9;5334:24;5305:63;:::i;:::-;5295:73;;;4132:1242;;;;;:::o;5379:1248::-;5511:6;5519;5572:2;5560:9;5551:7;5547:23;5543:32;5540:52;;;5588:1;5585;5578:12;5540:52;5628:9;5615:23;-1:-1:-1;;;;;5698:2:21;5690:6;5687:14;5684:34;;;5714:1;5711;5704:12;5684:34;5752:6;5741:9;5737:22;5727:32;;5797:7;5790:4;5786:2;5782:13;5778:27;5768:55;;5819:1;5816;5809:12;5768:55;5855:2;5842:16;5877:4;5901:68;5917:51;5965:2;5917:51;:::i;5901:68::-;5991:3;6015:2;6010:3;6003:15;6043:2;6038:3;6034:12;6027:19;;6074:2;6070;6066:11;6122:7;6117:2;6111;6108:1;6104:10;6100:2;6096:19;6092:28;6089:41;6086:61;;;6143:1;6140;6133:12;6086:61;6165:1;6156:10;;6175:238;6189:2;6186:1;6183:9;6175:238;;;6260:3;6247:17;6277:31;6302:5;6277:31;:::i;:::-;6321:18;;6207:1;6200:9;;;;;6359:12;;;;6391;;6175:238;;6632:202;6699:6;6752:2;6740:9;6731:7;6727:23;6723:32;6720:52;;;6768:1;6765;6758:12;6720:52;6791:37;6818:9;6791:37;:::i;6839:414::-;6924:6;6932;6985:2;6973:9;6964:7;6960:23;6956:32;6953:52;;;7001:1;6998;6991:12;6953:52;7024:37;7051:9;7024:37;:::i;:::-;7014:47;;7105:2;7094:9;7090:18;7084:25;-1:-1:-1;;;;;7124:6:21;7121:30;7118:50;;;7164:1;7161;7154:12;7118:50;7187:60;7239:7;7230:6;7219:9;7215:22;7187:60;:::i;7258:286::-;7316:6;7369:2;7357:9;7348:7;7344:23;7340:32;7337:52;;;7385:1;7382;7375:12;7337:52;7411:23;;-1:-1:-1;;;;;;7463:32:21;;7453:43;;7443:71;;7510:1;7507;7500:12;7549:414;7634:6;7642;7695:2;7683:9;7674:7;7670:23;7666:32;7663:52;;;7711:1;7708;7701:12;7663:52;7744:9;7738:16;-1:-1:-1;;;;;7769:6:21;7766:30;7763:50;;;7809:1;7806;7799:12;7763:50;7832:60;7884:7;7875:6;7864:9;7860:22;7832:60;:::i;:::-;7822:70;;;7911:46;7953:2;7942:9;7938:18;7911:46;:::i;:::-;7901:56;;7549:414;;;;;:::o;8234:492::-;8342:6;8350;8403:2;8391:9;8382:7;8378:23;8374:32;8371:52;;;8419:1;8416;8409:12;8371:52;8451:9;8445:16;8490:1;8483:5;8480:12;8470:40;;8506:1;8503;8496:12;8470:40;8578:2;8563:18;;8557:25;8529:5;;-1:-1:-1;;;;;;8594:30:21;;8591:50;;;8637:1;8634;8627:12;8731:630;8835:6;8888:3;8876:9;8867:7;8863:23;8859:33;8856:53;;;8905:1;8902;8895:12;8856:53;8938:2;8932:9;8980:3;8972:6;8968:16;9050:6;9038:10;9035:22;-1:-1:-1;;;;;9002:10:21;8999:34;8996:62;8993:88;;;9061:18;;:::i;:::-;9101:10;9097:2;9090:22;;9142:9;9136:16;9128:6;9121:32;9207:2;9196:9;9192:18;9186:25;9181:2;9173:6;9169:15;9162:50;9266:2;9255:9;9251:18;9245:25;9240:2;9232:6;9228:15;9221:50;9325:2;9314:9;9310:18;9304:25;9299:2;9291:6;9287:15;9280:50;9349:6;9339:16;;;8731:630;;;;:::o;9366:856::-;9457:6;9510:3;9498:9;9489:7;9485:23;9481:33;9478:53;;;9527:1;9524;9517:12;9478:53;9553:22;;:::i;:::-;9611:9;9598:23;9591:5;9584:38;9682:2;9671:9;9667:18;9654:32;9649:2;9642:5;9638:14;9631:56;9747:2;9736:9;9732:18;9719:32;9714:2;9707:5;9703:14;9696:56;9812:2;9801:9;9797:18;9784:32;9779:2;9772:5;9768:14;9761:56;9878:3;9867:9;9863:19;9850:33;9844:3;9837:5;9833:15;9826:58;9917:39;9951:3;9940:9;9936:19;9917:39;:::i;:::-;9911:3;9904:5;9900:15;9893:64;9990:37;10022:3;10011:9;10007:19;9990:37;:::i;:::-;9984:3;9977:5;9973:15;9966:62;10061:38;10094:3;10083:9;10079:19;10061:38;:::i;:::-;10055:3;10048:5;10044:15;10037:63;10119:3;10154:37;10187:2;10176:9;10172:18;10154:37;:::i;:::-;10138:14;;;10131:61;10142:5;9366:856;-1:-1:-1;;;9366:856:21:o;10227:1266::-;10421:6;10429;10437;10445;10453;10461;10469;10477;10521:9;10512:7;10508:23;10551:3;10547:2;10543:12;10540:32;;;10568:1;10565;10558:12;10540:32;10608:9;10595:23;-1:-1:-1;;;;;10678:2:21;10670:6;10667:14;10664:34;;;10694:1;10691;10684:12;10664:34;10717:72;10781:7;10772:6;10761:9;10757:22;10717:72;:::i;:::-;10707:82;;10842:2;10831:9;10827:18;10814:32;10798:48;;10871:2;10861:8;10858:16;10855:36;;;10887:1;10884;10877:12;10855:36;10926:60;10978:7;10967:8;10956:9;10952:24;10926:60;:::i;:::-;11005:8;;-1:-1:-1;10900:86:21;-1:-1:-1;11093:2:21;11078:18;;11065:32;;-1:-1:-1;11109:16:21;;;11106:36;;;11138:1;11135;11128:12;11106:36;;11177:60;11229:7;11218:8;11207:9;11203:24;11177:60;:::i;:::-;11256:8;;-1:-1:-1;11151:86:21;-1:-1:-1;;11325:3:21;-1:-1:-1;;11307:16:21;;11303:26;11300:46;;;11342:1;11339;11332:12;11300:46;-1:-1:-1;10227:1266:21;;;;-1:-1:-1;10227:1266:21;;;;-1:-1:-1;10227:1266:21;;11380:2;11365:18;;;-1:-1:-1;11430:3:21;11415:19;;11402:33;;11482:3;11467:19;11454:33;;-1:-1:-1;10227:1266:21:o;11498:929::-;11601:6;11609;11653:9;11644:7;11640:23;11683:3;11679:2;11675:12;11672:32;;;11700:1;11697;11690:12;11672:32;11724:4;11720:2;11716:13;11713:33;;;11742:1;11739;11732:12;11713:33;;11768:22;;:::i;:::-;11819:9;11813:16;11806:5;11799:31;11883:2;11872:9;11868:18;11862:25;11857:2;11850:5;11846:14;11839:49;11941:2;11930:9;11926:18;11920:25;11915:2;11908:5;11904:14;11897:49;11999:2;11988:9;11984:18;11978:25;11973:2;11966:5;11962:14;11955:49;12058:3;12047:9;12043:19;12037:26;12031:3;12024:5;12020:15;12013:51;12109:3;12098:9;12094:19;12088:26;12123:33;12148:7;12123:33;:::i;:::-;12183:3;12172:15;;12165:32;12242:3;12227:19;;12221:26;12256:33;12221:26;12256:33;:::i;:::-;12316:3;12305:15;;12298:32;12309:5;-1:-1:-1;12373:48:21;12415:4;12400:20;;12373:48;:::i;12432:180::-;12491:6;12544:2;12532:9;12523:7;12519:23;12515:32;12512:52;;;12560:1;12557;12550:12;12512:52;-1:-1:-1;12583:23:21;;12432:180;-1:-1:-1;12432:180:21:o;12617:457::-;12714:6;12722;12775:2;12763:9;12754:7;12750:23;12746:32;12743:52;;;12791:1;12788;12781:12;12743:52;12827:9;12814:23;12804:33;;12888:2;12877:9;12873:18;12860:32;-1:-1:-1;;;;;12907:6:21;12904:30;12901:50;;;12947:1;12944;12937:12;12901:50;12970:22;;13026:3;13008:16;;;13004:26;13001:46;;;13043:1;13040;13033:12;13079:1030;13219:6;13227;13235;13243;13251;13259;13312:3;13300:9;13291:7;13287:23;13283:33;13280:53;;;13329:1;13326;13319:12;13280:53;13365:9;13352:23;13342:33;;13426:2;13415:9;13411:18;13398:32;-1:-1:-1;;;;;13490:2:21;13482:6;13479:14;13476:34;;;13506:1;13503;13496:12;13476:34;13529:72;13593:7;13584:6;13573:9;13569:22;13529:72;:::i;:::-;13519:82;;13654:2;13643:9;13639:18;13626:32;13610:48;;13683:2;13673:8;13670:16;13667:36;;;13699:1;13696;13689:12;13667:36;13738:60;13790:7;13779:8;13768:9;13764:24;13738:60;:::i;:::-;13817:8;;-1:-1:-1;13712:86:21;-1:-1:-1;13905:2:21;13890:18;;13877:32;;-1:-1:-1;13921:16:21;;;13918:36;;;13950:1;13947;13940:12;13918:36;;13989:60;14041:7;14030:8;14019:9;14015:24;13989:60;:::i;:::-;13079:1030;;;;-1:-1:-1;13079:1030:21;;-1:-1:-1;13079:1030:21;;14068:8;;13079:1030;-1:-1:-1;;;13079:1030:21:o;14223:266::-;14311:6;14306:3;14299:19;14363:6;14356:5;14349:4;14344:3;14340:14;14327:43;-1:-1:-1;14415:1:21;14390:16;;;14408:4;14386:27;;;14379:38;;;;14471:2;14450:15;;;-1:-1:-1;;14446:29:21;14437:39;;;14433:50;;14223:266::o;14494:257::-;14535:3;14573:5;14567:12;14600:6;14595:3;14588:19;14616:63;14672:6;14665:4;14660:3;14656:14;14649:4;14642:5;14638:16;14616:63;:::i;:::-;14733:2;14712:15;-1:-1:-1;;14708:29:21;14699:39;;;;14740:4;14695:50;;14494:257;-1:-1:-1;;14494:257:21:o;14756:243::-;14843:1;14836:5;14833:12;14823:143;;14888:10;14883:3;14879:20;14876:1;14869:31;14923:4;14920:1;14913:15;14951:4;14948:1;14941:15;14823:143;14975:18;;14756:243::o;15004:884::-;15070:3;15116:5;15103:19;15131:33;15156:7;15131:33;:::i;:::-;-1:-1:-1;;;;;15223:16:21;;;15211:29;;15288:4;15277:16;;15264:30;;15303:33;15264:30;15303:33;:::i;:::-;15368:16;15361:4;15352:14;;15345:40;15441:4;15430:16;;;15417:30;15401:14;;;15394:54;15504:4;15493:16;;;15480:30;15464:14;;;15457:54;15567:4;15556:16;;;15543:30;15527:14;;;15520:54;15617:55;15666:4;15655:16;;15434:5;15617:55;:::i;:::-;15704:4;15697;15692:3;15688:14;15681:28;15730:69;15793:4;15788:3;15784:14;15770:12;15756;15730:69;:::i;:::-;15718:81;;;15855:4;15848:5;15844:16;15831:30;15824:4;15819:3;15815:14;15808:54;15878:4;15871:11;;;15004:884;;;;:::o;15893:1048::-;15954:3;15982:6;16022:5;16009:19;16004:3;15997:32;16085:4;16078:5;16074:16;16061:30;16054:4;16049:3;16045:14;16038:54;16148:4;16141:5;16137:16;16124:30;16117:4;16112:3;16108:14;16101:54;16203:4;16196:5;16192:16;16179:30;16218:33;16243:7;16218:33;:::i;:::-;-1:-1:-1;;;;;16321:16:21;;;16314:4;16305:14;;16298:40;16386:4;16375:16;;16362:30;;16401:33;16362:30;16401:33;:::i;:::-;16466:16;16459:4;16450:14;;16443:40;16531:4;16520:16;;16507:30;16546:33;16507:30;16546:33;:::i;:::-;-1:-1:-1;;;;;14180:31:21;16625:4;16616:14;;14168:44;16674:55;16723:4;16712:16;;16716:5;16674:55;:::i;:::-;16761:2;16754:4;16749:3;16745:14;16738:26;16785:67;16848:2;16843:3;16839:12;16825;16811;16785:67;:::i;:::-;16773:79;;;;16908:4;16901:5;16897:16;16884:30;16877:4;16872:3;16868:14;16861:54;16931:4;16924:11;;;15893:1048;;;;:::o;16946:680::-;17010:3;17067:5;17054:19;17112:5;17096:14;17092:26;17173:3;17169:8;17165:2;17161:17;17141:18;17137:42;17127:70;;17193:1;17190;17183:12;17127:70;17218:4;17213:3;17206:17;17244:89;17327:4;17322:3;17318:14;17310:5;17290:18;17286:30;17244:89;:::i;:::-;17232:101;-1:-1:-1;17394:4:21;17383:16;;17370:30;-1:-1:-1;;17445:17:21;;17419:44;;17409:72;;17477:1;17474;17467:12;17409:72;17523:3;17517:4;17513:14;17506:4;17501:3;17497:14;17490:38;17544:76;17615:4;17607:5;17585:20;17581:32;17544:76;:::i;17917:271::-;18100:6;18092;18087:3;18074:33;18056:3;18126:16;;18151:13;;;18126:16;17917:271;-1:-1:-1;17917:271:21:o;18193:274::-;18322:3;18360:6;18354:13;18376:53;18422:6;18417:3;18410:4;18402:6;18398:17;18376:53;:::i;:::-;18445:16;;;;;18193:274;-1:-1:-1;;18193:274:21:o;18472:940::-;18901:3;18939:6;18933:13;18955:53;19001:6;18996:3;18989:4;18981:6;18977:17;18955:53;:::i;:::-;-1:-1:-1;;;19030:16:21;;;19055:18;;;19098:13;;19120:65;19098:13;19172:1;19161:13;;19154:4;19142:17;;19120:65;:::i;:::-;-1:-1:-1;;;19248:1:21;19204:20;;;;19240:10;;;19233:23;19281:13;;19303:62;19281:13;19352:1;19344:10;;19337:4;19325:17;;19303:62;:::i;:::-;19385:17;19404:1;19381:25;;18472:940;-1:-1:-1;;;;;18472:940:21:o;19417:437::-;-1:-1:-1;;;19672:3:21;19665:35;19647:3;19729:6;19723:13;19745:62;19800:6;19795:2;19790:3;19786:12;19779:4;19771:6;19767:17;19745:62;:::i;:::-;19827:16;;;;19845:2;19823:25;;19417:437;-1:-1:-1;;19417:437:21:o;20665:668::-;-1:-1:-1;;;;;21024:15:21;;;21006:34;;21076:15;;;21071:2;21056:18;;21049:43;21128:15;;21123:2;21108:18;;21101:43;-1:-1:-1;;;;;;21180:33:21;;21175:2;21160:18;;21153:61;20955:3;20940:19;;21223:60;21278:3;21263:19;;21255:6;21223:60;:::i;:::-;21320:6;21314:3;21303:9;21299:19;21292:35;20665:668;;;;;;;;;:::o;21338:666::-;-1:-1:-1;;;;;21661:15:21;;;21643:34;;21713:15;;;21708:2;21693:18;;21686:43;21765:15;;21760:2;21745:18;;21738:43;-1:-1:-1;;;;;;21817:33:21;;21812:2;21797:18;;21790:61;21882:3;21867:19;;21860:35;;;21932:3;21623;21911:19;;21904:32;;;21586:4;;21953:45;;21978:19;;21970:6;21953:45;:::i;:::-;21945:53;21338:666;-1:-1:-1;;;;;;;;21338:666:21:o;22288:412::-;22530:1;22526;22521:3;22517:11;22513:19;22505:6;22501:32;22490:9;22483:51;22570:6;22565:2;22554:9;22550:18;22543:34;22613:2;22608;22597:9;22593:18;22586:30;22464:4;22633:61;22690:2;22679:9;22675:18;22667:6;22659;22633:61;:::i;22705:784::-;22933:2;22945:21;;;22918:18;;23001:22;;;22885:4;23080:6;23054:2;23039:18;;22885:4;23114:304;23128:6;23125:1;23122:13;23114:304;;;23203:6;23190:20;23223:31;23248:5;23223:31;:::i;:::-;-1:-1:-1;;;;;23279:31:21;23267:44;;23334:4;23393:15;;;;23358:12;;;;23307:1;23143:9;23114:304;;;-1:-1:-1;23469:4:21;23454:20;;;;23447:36;;;;-1:-1:-1;23435:3:21;22705:784;-1:-1:-1;;;22705:784:21:o;23686:485::-;23943:6;23936:14;23929:22;23918:9;23911:41;23988:6;23983:2;23972:9;23968:18;23961:34;24004:59;24059:2;24048:9;24044:18;24036:6;24004:59;:::i;:::-;24099:3;24094:2;24083:9;24079:18;24072:31;23892:4;24120:45;24160:3;24149:9;24145:19;24137:6;24120:45;:::i;25880:589::-;26161:3;26150:9;26143:22;26124:4;26188:45;26228:3;26217:9;26213:19;26205:6;26188:45;:::i;:::-;26283:6;26276:14;26269:22;26264:2;26253:9;26249:18;26242:50;26328:6;26323:2;26312:9;26308:18;26301:34;26383:9;26375:6;26371:22;26366:2;26355:9;26351:18;26344:50;26411:52;26456:6;26448;26411:52;:::i;:::-;26403:60;25880:589;-1:-1:-1;;;;;;;25880:589:21:o;26704:331::-;26879:50;26919:9;26911:6;26879:50;:::i;:::-;26965:2;26960;26949:9;26945:18;26938:30;26860:4;26985:44;27025:2;27014:9;27010:18;27002:6;26985:44;:::i;27040:219::-;27189:2;27178:9;27171:21;27152:4;27209:44;27249:2;27238:9;27234:18;27226:6;27209:44;:::i;34037:356::-;34239:2;34221:21;;;34258:18;;;34251:30;34317:34;34312:2;34297:18;;34290:62;34384:2;34369:18;;34037:356::o;38957:782::-;39310:3;39299:9;39292:22;39273:4;39337:70;39402:3;39391:9;39387:19;39379:6;39337:70;:::i;:::-;39443:6;39438:2;39427:9;39423:18;39416:34;39486:6;39481:2;39470:9;39466:18;39459:34;39541:9;39533:6;39529:22;39524:2;39513:9;39509:18;39502:50;39575:32;39600:6;39592;39575:32;:::i;:::-;39561:46;;39656:9;39648:6;39644:22;39638:3;39627:9;39623:19;39616:51;39684:49;39726:6;39718;39710;39684:49;:::i;:::-;39676:57;38957:782;-1:-1:-1;;;;;;;;;38957:782:21:o;39744:919::-;39900:4;39942:3;39931:9;39927:19;39919:27;;39979:6;39973:13;39962:9;39955:32;40043:4;40035:6;40031:17;40025:24;40018:4;40007:9;40003:20;39996:54;40106:4;40098:6;40094:17;40088:24;40081:4;40070:9;40066:20;40059:54;40169:4;40161:6;40157:17;40151:24;40144:4;40133:9;40129:20;40122:54;40232:4;40224:6;40220:17;40214:24;40207:4;40196:9;40192:20;40185:54;40324:1;40320;40315:3;40311:11;40307:19;40299:4;40291:6;40287:17;40281:24;40277:50;40270:4;40259:9;40255:20;40248:80;40396:4;40388;40380:6;40376:17;40370:24;40366:35;40359:4;40348:9;40344:20;40337:65;40449:4;40441:6;40437:17;40431:24;40464:53;40511:4;40500:9;40496:20;40482:12;-1:-1:-1;;;;;17791:34:21;17779:47;;17726:106;40464:53;-1:-1:-1;40536:6:21;40579:15;;;40573:22;17707:6;17696:18;40638;;;;17684:31;39744:919;:::o;41645:1150::-;42063:4;42092:3;42122:2;42111:9;42104:21;42148:67;42211:2;42200:9;42196:18;42188:6;42148:67;:::i;:::-;42134:81;;42263:9;42255:6;42251:22;42246:2;42235:9;42231:18;42224:50;42297:49;42339:6;42331;42323;42297:49;:::i;:::-;42283:63;;42394:9;42386:6;42382:22;42377:2;42366:9;42362:18;42355:50;42422:49;42464:6;42456;42448;42422:49;:::i;:::-;42414:57;;;42513:6;42507:13;42502:2;42491:9;42487:18;42480:41;42576:2;42568:6;42564:15;42558:22;42552:3;42541:9;42537:19;42530:51;42636:2;42628:6;42624:15;42618:22;42612:3;42601:9;42597:19;42590:51;42696:2;42688:6;42684:15;42678:22;42672:3;42661:9;42657:19;42650:51;42738:6;42732:3;42721:9;42717:19;42710:35;42782:6;42776:3;42765:9;42761:19;42754:35;41645:1150;;;;;;;;;;;:::o;42800:731::-;43131:3;43120:9;43113:22;43094:4;43158:68;43221:3;43210:9;43206:19;43198:6;43158:68;:::i;:::-;43274:9;43266:6;43262:22;43257:2;43246:9;43242:18;43235:50;43308:49;43350:6;43342;43334;43308:49;:::i;:::-;43294:63;;43405:9;43397:6;43393:22;43388:2;43377:9;43373:18;43366:50;43433:49;43475:6;43467;43459;43433:49;:::i;:::-;43425:57;;;43518:6;43513:2;43502:9;43498:18;43491:34;42800:731;;;;;;;;;:::o;43718:521::-;43795:4;43801:6;43861:11;43848:25;43955:2;43951:7;43940:8;43924:14;43920:29;43916:43;43896:18;43892:68;43882:96;;43974:1;43971;43964:12;43882:96;44001:33;;44053:20;;;-1:-1:-1;;;;;;44085:30:21;;44082:50;;;44128:1;44125;44118:12;44082:50;44161:4;44149:17;;-1:-1:-1;44192:14:21;44188:27;;;44178:38;;44175:58;;;44229:1;44226;44219:12;44244:332;44344:4;44402:11;44389:25;44496:3;44492:8;44481;44465:14;44461:29;44457:44;44437:18;44433:69;44423:97;;44516:1;44513;44506:12;44581:327;44676:4;44734:11;44721:25;44828:3;44824:8;44813;44797:14;44793:29;44789:44;44769:18;44765:69;44755:97;;44848:1;44845;44838:12;44913:252;44985:2;44979:9;45027:3;45015:16;;-1:-1:-1;;;;;45046:34:21;;45082:22;;;45043:62;45040:88;;;45108:18;;:::i;:::-;45144:2;45137:22;44913:252;:::o;45170:253::-;45242:2;45236:9;45284:4;45272:17;;-1:-1:-1;;;;;45304:34:21;;45340:22;;;45301:62;45298:88;;;45366:18;;:::i;45428:275::-;45499:2;45493:9;45564:2;45545:13;;-1:-1:-1;;45541:27:21;45529:40;;-1:-1:-1;;;;;45584:34:21;;45620:22;;;45581:62;45578:88;;;45646:18;;:::i;:::-;45682:2;45675:22;45428:275;;-1:-1:-1;45428:275:21:o;45708:191::-;45776:4;-1:-1:-1;;;;;45801:6:21;45798:30;45795:56;;;45831:18;;:::i;:::-;-1:-1:-1;45876:1:21;45872:14;45888:4;45868:25;;45708:191::o;45904:503::-;45962:5;45969:6;46029:3;46016:17;46115:2;46111:7;46100:8;46084:14;46080:29;46076:43;46056:18;46052:68;46042:96;;46134:1;46131;46124:12;46042:96;46162:33;;46266:4;46253:18;;;-1:-1:-1;46214:21:21;;-1:-1:-1;;;;;;46283:30:21;;46280:50;;;46326:1;46323;46316:12;46280:50;46376:6;46360:14;46356:27;46346:8;46342:42;46339:62;;;46397:1;46394;46387:12;46412:224;46451:3;46479:6;46512:2;46509:1;46505:10;46542:2;46539:1;46535:10;46573:3;46569:2;46565:12;46560:3;46557:21;46554:47;;;46581:18;;:::i;:::-;46617:13;;46412:224;-1:-1:-1;;;;46412:224:21:o;46641:128::-;46681:3;46712:1;46708:6;46705:1;46702:13;46699:39;;;46718:18;;:::i;:::-;-1:-1:-1;46754:9:21;;46641:128::o;46774:217::-;46814:1;46840;46830:132;;46884:10;46879:3;46875:20;46872:1;46865:31;46919:4;46916:1;46909:15;46947:4;46944:1;46937:15;46830:132;-1:-1:-1;46976:9:21;;46774:217::o;46996:168::-;47036:7;47102:1;47098;47094:6;47090:14;47087:1;47084:21;47079:1;47072:9;47065:17;47061:45;47058:71;;;47109:18;;:::i;:::-;-1:-1:-1;47149:9:21;;46996:168::o;47169:125::-;47209:4;47237:1;47234;47231:8;47228:34;;;47242:18;;:::i;:::-;-1:-1:-1;47279:9:21;;47169:125::o;47299:258::-;47371:1;47381:113;47395:6;47392:1;47389:13;47381:113;;;47471:11;;;47465:18;47452:11;;;47445:39;47417:2;47410:10;47381:113;;;47512:6;47509:1;47506:13;47503:48;;;-1:-1:-1;;47547:1:21;47529:16;;47522:27;47299:258::o;47691:135::-;47730:3;-1:-1:-1;;47751:17:21;;47748:43;;;47771:18;;:::i;:::-;-1:-1:-1;47818:1:21;47807:13;;47691:135::o;47831:127::-;47892:10;47887:3;47883:20;47880:1;47873:31;47923:4;47920:1;47913:15;47947:4;47944:1;47937:15;48095:127;48156:10;48151:3;48147:20;48144:1;48137:31;48187:4;48184:1;48177:15;48211:4;48208:1;48201:15;48227:127;48288:10;48283:3;48279:20;48276:1;48269:31;48319:4;48316:1;48309:15;48343:4;48340:1;48333:15;48359:127;48420:10;48415:3;48411:20;48408:1;48401:31;48451:4;48448:1;48441:15;48475:4;48472:1;48465:15;48491:131;-1:-1:-1;;;;;48566:31:21;;48556:42;;48546:70;;48612:1;48609;48602:12

Swarm Source

ipfs://ef137c0ceaa4ff6388385b5911e82c255a8a52c5ebfeb89aed96950deeb92c36
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading