{
  "language": "Solidity",
  "sources": {
    "contracts/access/OwnerWithdrawable.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol';\n\n/// @author Alexandas\n/// @dev Make the contract owner can withdraw token and eth\nabstract contract OwnerWithdrawable is OwnableUpgradeable {\n\tusing SafeERC20Upgradeable for IERC20Upgradeable;\n\n\t/// @dev emit when token is withdrawn\n\t/// @param token token address\n\t/// @param to receiver address\n\t/// @param value token value\n\tevent Withdrawal(IERC20Upgradeable token, address to, uint256 value);\n\n\t/// @dev emit when ETH is withdrawn\n\t/// @param to receiver address\n\t/// @param value token value\n\tevent NativeWithdrawal(address to, uint256 value);\n\n\t/// @dev withdraw token\n\t/// @param token token address\n\t/// @param to receiver address\n\t/// @param value token value\n\tfunction ownerWithdrawERC20(\n\t\tIERC20Upgradeable token,\n\t\taddress to,\n\t\tuint256 value\n\t) external onlyOwner {\n\t\ttoken.safeTransfer(to, value);\n\t\temit Withdrawal(token, to, value);\n\t}\n\n\t/// @dev withdraw ETH\n\t/// @param to receiver address\n\t/// @param value token value\n\tfunction ownerWithdrawNative(address payable to, uint256 value) external onlyOwner {\n\t\tbool success = to.send(value);\n\t\trequire(success, 'OwnerWithdrawable: withdraw native token failed');\n\t\temit NativeWithdrawal(to, value);\n\t}\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20Upgradeable.sol\";\n"
    },
    "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n    using AddressUpgradeable for address;\n\n    function safeTransfer(\n        IERC20Upgradeable token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20Upgradeable token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20Upgradeable token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20Upgradeable token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20Upgradeable token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = _setInitializedVersion(1);\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n     * initialization step. This is essential to configure modules that are added through upgrades and that require\n     * initialization.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     */\n    modifier reinitializer(uint8 version) {\n        bool isTopLevelCall = _setInitializedVersion(version);\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(version);\n        }\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     */\n    function _disableInitializers() internal virtual {\n        _setInitializedVersion(type(uint8).max);\n    }\n\n    function _setInitializedVersion(uint8 version) private returns (bool) {\n        // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n        // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n        // of initializers, because in other contexts the contract may have been reentered.\n        if (_initializing) {\n            require(\n                version == 1 && !AddressUpgradeable.isContract(address(this)),\n                \"Initializable: contract is already initialized\"\n            );\n            return false;\n        } else {\n            require(_initialized < version, \"Initializable: contract is already initialized\");\n            _initialized = version;\n            return true;\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n}\n"
    },
    "contracts/wallets/FundPool.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol';\n\nimport '../govers/RouterWrapper.sol';\nimport '../access/OwnerWithdrawable.sol';\nimport '../access/Pauser.sol';\n\n/// @author Alexandas\n/// @dev FundPool contract\ncontract FundPool is IFundPool, OwnerWithdrawable, Pauser, ReentrancyGuardUpgradeable, RouterWrapper {\n\tusing SafeMathUpgradeable for uint256;\n\tusing SafeERC20Upgradeable for IERC20Upgradeable;\n\n\t/// @dev account balances\n\tmapping(address => mapping(bytes32 => uint256)) internal balances;\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param pauser contract pauser\n\t/// @param router router contract address\n\tfunction initialize(\n\t\taddress owner,\n\t\taddress pauser,\n\t\tIRouter router\n\t) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Pauser(pauser);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev recharge for account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount token amount\n\tfunction recharge(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount\n\t) external override whenNotPaused nonReentrant {\n\t\trequire(amount > 0, 'FundPool: zero amount');\n\t\taddress wallet = router.ProviderController().walletOf(provider, account);\n\t\trequire(wallet != address(0), 'FundPool: nonexistent wallet');\n\t\trequire(wallet == msg.sender, 'FundPool: caller is not the account wallet');\n\t\t_recharge(provider, account, amount);\n\t}\n\n\tfunction _recharge(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount\n\t) internal {\n\t\tbalances[provider][account] = balances[provider][account].add(amount);\n\t\trouter.Token().safeTransferFrom(msg.sender, address(this), amount);\n\t\temit Recharged(provider, account, amount);\n\t}\n\n\t/// @dev spend bills for account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param bills billing data\n\t/// @param timeout tx timeout\n\t/// @param nonce billing nonce\n\t/// @param signature provider signature\n\t/// @return fee bills fee\n\tfunction spend(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tbytes memory bills,\n\t\tuint256 timeout,\n\t\tuint64 nonce,\n\t\tbytes memory signature\n\t) external override whenNotPaused nonReentrant returns (uint256 fee) {\n\t\trequire(bills.length > 0, 'FundPool: invalid bills');\n\t\trequire(router.ProviderController().accountExists(provider, account), 'FundPool: nonexistent account');\n\t\tfee = _spend(provider, account, bills, timeout, nonce, signature);\n\t}\n\n\tfunction _spend(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tbytes memory bills,\n\t\tuint256 timeout,\n\t\tuint64 nonce,\n\t\tbytes memory signature\n\t) internal returns (uint256 amount) {\n\t\tif (bills.length > 0) {\n\t\t\tIBilling billing = router.Billing();\n\t\t\tamount = billing.spend(provider, account, bills, timeout, nonce, signature);\n\t\t\tuint256 balance = balanceOf(provider, account);\n\t\t\trequire(balance >= amount, 'FundPool: insufficient balance for billing fee');\n\t\t\tbalances[provider][account] = balances[provider][account].sub(amount);\n\t\t\trouter.Token().safeTransfer(address(billing), amount);\n\t\t}\n\t\temit Spent(provider, account, amount);\n\t}\n\n\t/// @dev withdraw token for account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param bills billing data\n\t/// @param timeout tx timeout\n\t/// @param nonce billing nonce\n\t/// @param signature billing signature\n\t/// @param to token receiver\n\t/// @param amount token amount\n\t/// @param signature provider signature\n\t/// @return fee bill fee\n\tfunction withdraw(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tbytes memory bills,\n\t\tuint256 timeout,\n\t\tuint64 nonce,\n\t\tbytes memory signature,\n\t\taddress to,\n\t\tuint256 amount\n\t) external override whenNotPaused nonReentrant returns (uint256 fee) {\n\t\tIProviderController controller = router.ProviderController();\n\t\trequire(controller.walletOf(provider, account) == msg.sender, 'FundPool: caller is not the wallet for the account');\n\t\tfee = _spend(provider, account, bills, timeout, nonce, signature);\n\t\trequire(balanceOf(provider, account) >= amount, 'FundPool: insufficient balance for withdrawal');\n\t\tbalances[provider][account] = balances[provider][account].sub(amount);\n\t\trouter.Token().safeTransfer(to, amount);\n\t\temit Withdrawn(provider, account, to, amount);\n\t}\n\n\t/// @dev return wallet of the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return wallet of the account\n\tfunction walletOf(address provider, bytes32 account) public view override returns (address) {\n\t\treturn router.ProviderController().walletOf(provider, account);\n\t}\n\n\t/// @dev return balance of account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return balance of account account\n\tfunction balanceOf(address provider, bytes32 account) public view returns (uint256) {\n\t\trequire(router.ProviderController().accountExists(provider, account), 'FundPool: nonexistent provider');\n\t\treturn balances[provider][account];\n\t}\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a + b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a * b;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator.\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a % b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {trySub}.\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b <= a, errorMessage);\n            return a - b;\n        }\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a / b;\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting with custom message when dividing by zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryMod}.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a % b;\n        }\n    }\n}\n"
    },
    "contracts/govers/RouterWrapper.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\nimport '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';\nimport '../interfaces/IRouter.sol';\n\n/// @author Alexandas\n/// @dev Router wrapper contract\nabstract contract RouterWrapper is Initializable {\n\t/// @dev router contract address\n\tIRouter public router;\n\n\t/// @dev emit when provider registry contract updated\n\t/// @param router contract address\n\tevent RouterUpdated(IRouter router);\n\n\tmodifier onlyGovernance() {\n\t\tIGovernance governance = router.Governance();\n\t\trequire(msg.sender == address(governance), 'RouterWrapper: caller is not the governance');\n\t\t_;\n\t}\n\n\tmodifier onlyProviderController() {\n\t\tIProviderController controller = router.ProviderController();\n\t\trequire(msg.sender == address(controller), 'RouterWrapper: caller is not the provider controller');\n\t\t_;\n\t}\n\n\tmodifier onlyProvider() {\n\t\tIProviderRegistry providerRegistry = router.ProviderRegistry();\n\t\trequire(providerRegistry.isProvider(msg.sender), 'RouterWrapper: caller is not the provider');\n\t\t_;\n\t}\n\n\tmodifier onlyMessageReceiver() {\n\t\taddress messageReceiver = router.MessageReceiver();\n\t\trequire(msg.sender == messageReceiver, 'RouterWrapper: caller is not message receiver');\n\t\t_;\n\t}\n\n\tmodifier onlyDstChainPayment() {\n\t\tIDstChainPayment dstChainPayment = router.DstChainPayment();\n\t\trequire(msg.sender == address(dstChainPayment), 'RouterWrapper: caller is not dst chain payment');\n\t\t_;\n\t}\n\n\tmodifier onlyFundPool() {\n\t\tIFundPool pool = router.FundPool();\n\t\trequire(msg.sender == address(pool), 'RouterWrapper: caller is not fund pool');\n\t\t_;\n\t}\n\n\t/// @dev initialize provider registry contract\n\t/// @param _router contract address\n\tfunction __Init_Router(IRouter _router) internal onlyInitializing {\n\t\t_setRouter(_router);\n\t}\n\n\tfunction _setRouter(IRouter _router) internal {\n\t\trequire(address(_router) != address(0), 'RouterWrapper: zero address');\n\t\trouter = _router;\n\t\temit RouterUpdated(_router);\n\t}\n}\n"
    },
    "contracts/access/Pauser.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol';\n\n/// @author Alexandas\n/// @dev Pauser contract\nabstract contract Pauser is OwnableUpgradeable, PausableUpgradeable {\n\t/// @dev all pausers\n\tmapping(address => bool) public pausers;\n\n\t/// @dev emit when pauser is added\n\t/// @param account pauser address\n\tevent PauserAdded(address account);\n\n\t/// @dev emit when pauser is removed\n\t/// @param account pauser address\n\tevent PauserRemoved(address account);\n\n\tfunction __Init_Pauser(address account) internal onlyInitializing {\n\t\t_addPauser(account);\n\t}\n\n\tmodifier onlyPauser() {\n\t\trequire(isPauser(msg.sender), 'Pauser: caller is not the pauser');\n\t\t_;\n\t}\n\n\t/// @dev pause the contract\n\tfunction pause() public onlyPauser {\n\t\t_pause();\n\t}\n\n\t/// @dev unpause the contract\n\tfunction unpause() public onlyPauser {\n\t\t_unpause();\n\t}\n\n\t/// @dev whether the account is the contract pauser\n\t/// @param account address\n\t/// @return whether account is a pauser\n\tfunction isPauser(address account) public view returns (bool) {\n\t\treturn pausers[account];\n\t}\n\n\t/// @dev add a pauser for the contract\n\t/// @param account address\n\tfunction addPauser(address account) public onlyOwner {\n\t\t_addPauser(account);\n\t}\n\n\t/// @dev remove a pauser for the contract\n\t/// @param account address\n\tfunction removePauser(address account) public onlyOwner {\n\t\t_removePauser(account);\n\t}\n\n\t/// @dev remove a pauser for the contract\n\tfunction renouncePauser() public {\n\t\t_removePauser(msg.sender);\n\t}\n\n\tfunction _addPauser(address account) private {\n\t\trequire(!isPauser(account), 'Pauser: account is already pauser');\n\t\tpausers[account] = true;\n\t\temit PauserAdded(account);\n\t}\n\n\tfunction _removePauser(address account) private {\n\t\trequire(isPauser(account), 'Pauser: account is not pauser');\n\t\tdelete pausers[account];\n\t\temit PauserRemoved(account);\n\t}\n}\n"
    },
    "contracts/interfaces/IRouter.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol';\n\nimport '../interfaces/IGovernance.sol';\nimport '../interfaces/IProviderRegistry.sol';\nimport '../interfaces/IProviderController.sol';\nimport '../interfaces/IDstChainPayment.sol';\nimport '../interfaces/IBilling.sol';\nimport '../interfaces/IFundPool.sol';\nimport '../resources/interfaces/INormalResourceController.sol';\nimport '../resources/interfaces/IIPFSStorageController.sol';\nimport '../resources/interfaces/IResourcePriceAdaptor.sol';\n\n/// @author Alexandas\n/// @dev Router interface\ninterface IRouter {\n\t/// @dev emit when governance contract address updated\n\t/// @param governance governance contract address\n\tevent GovernanceUpdated(IGovernance governance);\n\n\t/// @dev emit when message receiver updated\n\t/// @param messageReceiver message receiver contract address\n\tevent MessageReceiverUpdated(address messageReceiver);\n\n\t/// @dev emit when provider registry contract updated\n\t/// @param _providerRegistry provider registry contract\n\tevent ProviderRegistryUpdated(IProviderRegistry _providerRegistry);\n\n\t/// @dev emit when dst ProviderController contract address updated\n\t/// @param providerController ProviderController contract address\n\tevent ProviderControllerUpdated(IProviderController providerController);\n\n\t/// @dev emit when token updated\n\t/// @param token token address\n\tevent TokenUpdated(IERC20Upgradeable token);\n\n\t/// @dev emit when building time controller updated\n\t/// @param buildingTimeController building time controller contract\n\tevent BuildingTimeControllerUpdated(INormalResourceController buildingTimeController);\n\n\t/// @dev emit when bandwidth controller updated\n\t/// @param bandwidthController bandwidth controller contract\n\tevent BandwidthControllerUpdated(INormalResourceController bandwidthController);\n\n\t/// @dev emit when AR storage controller updated\n\t/// @param arStorageController AR storage controller contract\n\tevent ARStorageControllerUpdated(INormalResourceController arStorageController);\n\n\t/// @dev emit when ipfs storage controller updated\n\t/// @param ipfsStorageController IPFS storage controller contract\n\tevent IPFSStorageControllerUpdated(IIPFSStorageController ipfsStorageController);\n\n\t/// @dev emit when resource price adaptor updated\n\t/// @param resourcePriceAdaptor resource price adaptor contract\n\tevent ResourcePriceAdaptorUpdated(IResourcePriceAdaptor resourcePriceAdaptor);\n\n\t/// @dev emit when dst chain payment contract address updated\n\t/// @param dstChainPayment dst chain payment contract address\n\tevent DstChainPaymentUpdated(IDstChainPayment dstChainPayment);\n\n\t/// @dev emit when billing contract updated\n\t/// @param billing billing contract\n\tevent BillingUpdated(IBilling billing);\n\n\t/// @dev emit when fund pool contract updated\n\t/// @param fundPool fund pool contract\n\tevent FundPoolUpdated(IFundPool fundPool);\n\n\t/// @dev message receiver contract address\n\tfunction MessageReceiver() external view returns (address);\n\n\t/// @dev Governance contract address\n\tfunction Governance() external view returns (IGovernance);\n\n\t/// @dev providers contract address\n\tfunction ProviderRegistry() external view returns (IProviderRegistry);\n\n\t/// @dev provider controller contract address\n\tfunction ProviderController() external view returns (IProviderController);\n\n\t/// @dev token address\n\tfunction Token() external view returns (IERC20Upgradeable);\n\n\t/// @dev return building time controller\n\tfunction BuildingTimeController() external view returns (INormalResourceController);\n\n\t/// @dev return bandwidth controller\n\tfunction BandwidthController() external view returns (INormalResourceController);\n\n\t/// @dev return AR storage controller\n\tfunction ARStorageController() external view returns (INormalResourceController);\n\n\t/// @dev return ipfs storage controller\n\tfunction IPFSStorageController() external view returns (IIPFSStorageController);\n\n\t/// @dev return resource price adaptor contract address\n\tfunction ResourcePriceAdaptor() external view returns (IResourcePriceAdaptor);\n\n\t/// @dev dst chain payment contract address\n\tfunction DstChainPayment() external view returns (IDstChainPayment);\n\n\t/// @dev billing contract address\n\tfunction Billing() external view returns (IBilling);\n\n\t/// @dev fund pool contract address\n\tfunction FundPool() external view returns (IFundPool);\n}\n"
    },
    "contracts/interfaces/IGovernance.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport './IProviderRegistry.sol';\nimport '../libraries/ResourceData.sol';\n\n/// @author Alexandas\n/// @dev Governance interface\ninterface IGovernance {\n\t/// @dev emit when governance drip resource to provider\n\t/// @param provider provider address\n\tevent GovernanceDrip(address provider);\n\n\t/// @dev add a provider\n\t/// @param provider address\n\tfunction addProvider(address provider) external;\n\n\t/// @dev remove a provider\n\t/// @param provider address\n\tfunction removeProvider(address provider) external;\n\n\t/// @dev drip resource to provider\n\t/// @param provider provider address\n\t/// @param payloads resource payloads\n\tfunction drip(address provider, ResourceData.AmountPayload[] memory payloads) external;\n}\n"
    },
    "contracts/interfaces/IProviderRegistry.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\n/// @author Alexandas\n/// @dev provider registry interface\ninterface IProviderRegistry {\n\t/// @dev emit when provider is added\n\t/// @param provider provider address\n\tevent AddProvider(address provider);\n\n\t/// @dev emit when provider removed\n\t/// @param provider provider address\n\tevent RemoveProvider(address provider);\n\n\tevent AddProivderWallet(address provider, address wallet);\n\n\tevent RemoveProviderWallet(address provider, address wallet);\n\n\t/// @dev add a provider\n\t/// @param provider address\n\tfunction addProvider(address provider) external;\n\n\t/// @dev remove a provider\n\t/// @param provider address\n\tfunction removeProvider(address provider) external;\n\n\t/// @dev return whether address is a provider\n\t/// @param provider address\n\tfunction isProvider(address provider) external view returns (bool);\n\n\t/// @dev return provider wallet\n\t/// @param provider address\n\t/// @return provider wallet\n\tfunction providerWallet(address provider) external view returns (address);\n\n\t/// @dev return provider wallet exists\n\t/// @param provider address\n\t/// @return whether provider wallet exists\n\tfunction providerWalletExists(address provider) external view returns (bool);\n\n\t/// @dev return whether a valid signature\n\t/// @param provider address\n\t/// @param hash message hash\n\t/// @param signature provider signature for message hash\n\t/// @return is valid signature\n\tfunction isValidSignature(\n\t\taddress provider,\n\t\tbytes32 hash,\n\t\tbytes memory signature\n\t) external returns (bool);\n}\n"
    },
    "contracts/interfaces/IProviderController.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '../libraries/ResourceData.sol';\n\n/// @author Alexandas\n/// @dev provider controller interface\ninterface IProviderController {\n\t/// @dev emit when account registered in provider\n\t/// @param provider provider address\n\t/// @param account user account\n\tevent AccountRegistered(address provider, bytes32 account);\n\n\t/// @dev emit when provider drip resource to account\n\t/// @param provider provider address\n\t/// @param account user account\n\tevent ProviderDripped(address provider, bytes32 account);\n\n\t/// @dev emit when wallet types hash updated\n\t/// @param hash wallet types hash\n\tevent WalletTypesHashUpdated(bytes32 hash);\n\n\t/// @dev emit when wallet transferred\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param from original wallet address\n\t/// @param to new wallet address\n\tevent WalletTransferred(address provider, bytes32 account, address from, address to);\n\n\t/// @dev keccak256(\"Wallet(address provider,bytes32 account,address wallet)\")\n\tfunction walletTypesHash() external view returns (bytes32);\n\n\t/// @dev register account\n\t/// @param account user account\n\tfunction registerAccount(bytes32 account) external;\n\n\t/// @dev register multiple account\n\t/// @param accounts user accounts\n\tfunction registerMult(bytes32[] memory accounts) external;\n\n\t/// @dev Explain to a developer any extra details\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return whether account exists\n\tfunction accountExists(address provider, bytes32 account) external view returns (bool);\n\n\t/// @dev provider drip resource to multiple accounts\n\t/// @param accounts user accounts\n\t/// @param payloads resource amount payloads\n\tfunction dripMult(\n\t\tbytes32[] memory accounts,\n\t\tResourceData.AmountPayload[][] memory payloads\n\t) external;\n\n\t/// @dev provider drip resource to user account\n\t/// @param account user account\n\t/// @param payloads resource amount payloads\n\tfunction drip(\n\t\tbytes32 account,\n\t\tResourceData.AmountPayload[] memory payloads\n\t) external;\n\n\t/// @dev provider register and drip resource for multiple accounts\n\t/// @param accounts user accounts\n\t/// @param payloads resource amount payloads\n\tfunction registerAndDripMult(\n\t\tbytes32[] memory accounts,\n\t\tResourceData.AmountPayload[][] memory payloads\n\t) external;\n\n\t/// @dev initialize wallet for the given account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param wallet account wallet\n\t/// @param signature provider signature\n\tfunction initWallet(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\taddress wallet,\n\t\tbytes memory signature\n\t) external;\n\n\t/// @dev transfer wallet for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param newWallet account wallet\n\tfunction transferWallet(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\taddress newWallet\n\t) external;\n\n\t/// @dev return wallet for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return wallet for the account\n\tfunction walletOf(address provider, bytes32 account) external view returns (address);\n\n\t/// @dev return whether wallet exists\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return whether wallet exists\n\tfunction walletExists(address provider, bytes32 account) external view returns (bool);\n}\n"
    },
    "contracts/interfaces/IDstChainPayment.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol';\nimport '../libraries/ResourceData.sol';\n\n/// @author Alexandas\n/// @dev DstChainPayment interface\ninterface IDstChainPayment {\n\tstruct PaymentPayload {\n\t\taddress provider;\n\t\tuint64 nonce;\n\t\tbytes32 account;\n\t\tResourceData.ValuePayload[] payloads;\n\t}\n\n\t/// @dev emit when a user paid\n\t/// @param token token address\n\t/// @param payload payment payload\n\tevent Paid(IERC20Upgradeable token, PaymentPayload payload);\n\n\t/// @dev pay from source chain only called by message receiver\n\t/// @param _token token address\n\t/// @param dstAmount token amount\n\t/// @param message payment payload message bytes\n\tfunction payFromSourceChain(\n\t\tIERC20Upgradeable _token,\n\t\tuint256 dstAmount,\n\t\tbytes calldata message\n\t) external;\n\n\t/// @dev pay on dst chain\n\t/// @param payload payment payload\n\t/// @return value payment value\n\tfunction pay(PaymentPayload memory payload) external returns (uint256 value);\n\n\t/// @dev decode source chain message\n\t/// @param message message bytes\n\t/// @return provider provider address\n\t/// @return nonce nonce\n\t/// @return account user account\n\t/// @return payloads payment payloads\n\tfunction decodeSourceChainMessage(bytes memory message)\n\t\texternal\n\t\tview\n\t\treturns (\n\t\t\taddress provider,\n\t\t\tuint64 nonce,\n\t\t\tbytes32 account,\n\t\t\tResourceData.ValuePayload[] memory payloads\n\t\t);\n\n\t/// @dev calculate fee for ipfs storage and expiration\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount ipfs storage amount\n\t/// @param expiration ipfs expiration(in seconds)\n\t/// @return storageFee ipfs storage fee\n\t/// @return expirationFee ipfs expiration fee\n\tfunction ipfsAlloctionsFee(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount,\n\t\tuint256 expiration\n\t) external view returns (uint256 storageFee, uint256 expirationFee);\n\n\t/// @dev calculate ipfs storage and expiration with storage fee and expiration fee\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param storageFee storage fee\n\t/// @param expirationFee expiration fee\n\t/// @return amount ipfs storage amount\n\t/// @return expiration ipfs expiration(in seconds)\n\tfunction ipfsAllocations(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 storageFee,\n\t\tuint256 expirationFee\n\t) external view returns (uint256 amount, uint256 expiration);\n\n\t/// @dev return balance of provider\n\t/// @param provider provider address\n\t/// @return balance of provider\n\tfunction balanceOf(address provider) external view returns (uint256);\n\n\t/// @dev return resource price\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @return resource price\n\tfunction priceOf(address provider, ResourceData.ResourceType resourceType) external view returns (uint256);\n\n\t/// @dev return value of amount resource\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param amount resource amount\n\t/// @return token value\n\tfunction getValueOf(\n\t\taddress provider,\n\t\tResourceData.ResourceType resourceType,\n\t\tuint256 amount\n\t) external view returns (uint256);\n\n\t/// @dev return resource amount with value\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param value token value\n\t/// @return resource amount\n\tfunction getAmountOf(\n\t\taddress provider,\n\t\tResourceData.ResourceType resourceType,\n\t\tuint256 value\n\t) external view returns (uint256);\n}\n"
    },
    "contracts/interfaces/IBilling.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol';\nimport '../libraries/ResourceData.sol';\nimport '../resources/interfaces/IResourcePriceAdaptor.sol';\n\n/// @author Alexandas\n/// @dev Billing interface\ninterface IBilling {\n\tstruct BillEntry {\n\t\tResourceData.ResourceType resourceType;\n\t\tuint256 amount;\n\t}\n\n\tstruct Bill {\n\t\tuint256 indexBlock;\n\t\tBillEntry[] entries;\n\t}\n\n\t/// @dev emit when billing types hash updated\n\t/// @param hash billing types Hash\n\tevent BillingTypesHashUpdated(bytes32 hash);\n\n\t/// @dev emit when bills finalized\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param bills bills data\n\t/// @param amount fee\n\t/// @param nonce nonce\n\tevent Billing(address provider, bytes32 account, bytes bills, uint256 amount, uint64 nonce);\n\n\t/// @dev get billing types hash\n\t/// @return billing types hash\n\tfunction billingTypesHash() external view returns (bytes32);\n\n\t/// @dev spend bills\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param bills billing data\n\t/// @param timeout tx timeout\n\t/// @param nonce billing nonce\n\t/// @param signature billing signature\n\t/// @return fee billing fee\n\tfunction spend(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tbytes memory bills,\n\t\tuint256 timeout,\n\t\tuint64 nonce,\n\t\tbytes memory signature\n\t) external returns (uint256 fee);\n\n\t/// @dev return balance of provider\n\t/// @param provider provider address\n\t/// @return balance of provider\n\tfunction balanceOf(address provider) external view returns (uint256);\n\n\t/// @dev provider nonces for account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param nonce nonce\n\t/// @return whether nonce exists\n\tfunction nonceExists(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint64 nonce\n\t) external view returns (bool);\n}\n"
    },
    "contracts/interfaces/IFundPool.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\n/// @author Alexandas\n/// @dev FundPool interface\ninterface IFundPool {\n\n\t/// @dev emit when bill spent\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount token amount\n\tevent Spent(address provider, bytes32 account, uint256 amount);\n\n\t/// @dev emit when account recharged\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount token amount\n\tevent Recharged(address provider, bytes32 account, uint256 amount);\n\n\t/// @dev emit when user withdrawn\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param to token receiver\n\t/// @param amount token amount\n\tevent Withdrawn(address provider, bytes32 account, address to, uint256 amount);\n\n\t/// @dev recharge for account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount token amount\n\tfunction recharge(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount\n\t) external;\n\n\t/// @dev spend bills for account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param bills billing data\n\t/// @param timeout tx timeout\n\t/// @param nonce billing nonce\n\t/// @param signature provider signature\n\t/// @return fee bills fee\n\tfunction spend(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tbytes memory bills,\n\t\tuint256 timeout,\n\t\tuint64 nonce,\n\t\tbytes memory signature\n\t) external returns (uint256 fee);\n\n\t/// @dev withdraw token for account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param bills billing data\n\t/// @param timeout tx timeout\n\t/// @param nonce billing nonce\n\t/// @param signature billing signature\n\t/// @param to token receiver\n\t/// @param amount token amount\n\t/// @param signature provider signature\n\t/// @return fee bill fee\n\tfunction withdraw(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tbytes memory bills,\n\t\tuint256 timeout,\n\t\tuint64 nonce,\n\t\tbytes memory signature,\n\t\taddress to,\n\t\tuint256 amount\n\t) external returns (uint256 fee);\n\n\t/// @dev return wallet of the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return wallet of the account\n\tfunction walletOf(address provider, bytes32 account) external view returns (address);\n\n\t/// @dev return balance of account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return balance of account account\n\tfunction balanceOf(address provider, bytes32 account) external view returns (uint256);\n}\n"
    },
    "contracts/resources/interfaces/INormalResourceController.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\n/// @author Alexandas\n/// @dev normal resource controller interface\ninterface INormalResourceController {\n\n\t/// @dev emit when resource allocated for the provider\n\t/// @param provider provider address\n\t/// @param amount ipfs storage amount\n\tevent ProviderAllocated(address provider, uint256 amount);\n\n\t/// @dev emit when resource allocated for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount ipfs storage amount\n\tevent AccountAllocated(address provider, bytes32 account, uint256 amount);\n\n\t/// @dev allocate resource for the provider\n\t/// @param provider provider address\n\t/// @param amount resource amount\n\tfunction allocateProvider(address provider, uint256 amount) external;\n\n\t/// @dev allocate user's resource balance\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount resource amount\n\tfunction paymentAllocate(address provider, bytes32 account, uint256 amount) external;\n\n\t/// @dev provider drip resource to account directly\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount resource amount\n\tfunction drip(address provider, bytes32 account, uint256 amount) external;\n\n\t/// @dev resource balance\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return balance of the account\n\tfunction balanceOf(address provider, bytes32 account) external view returns (uint256);\n\n\t/// @dev resource balance\n\t/// @param provider provider address\n\t/// @return balance of the account\n\tfunction providerBalanceOf(address provider) external view returns (uint256);\n\n}\n"
    },
    "contracts/resources/interfaces/IIPFSStorageController.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\nimport '@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol';\n\n/// @author Alexandas\n/// @dev IPFS storage controller interface\ninterface IIPFSStorageController {\n\tstruct Storage {\n\t\tuint256 startTime;\n\t\tuint256 expiration;\n\t\tuint256 amount;\n\t}\n\n\t/// @dev emit when ipfs storage allocated for the provider\n\t/// @param provider provider address\n\t/// @param amount ipfs storage amount\n\t/// @param expiration ipfs storage expiration\n\tevent ProviderAllocated(address provider, uint256 amount, uint256 expiration);\n\n\t/// @dev emit when ipfs storage allocated for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount ipfs storage amount\n\t/// @param expiration ipfs storage expiration\n\tevent AccountAllocated(address provider, bytes32 account, uint256 amount, uint256 expiration);\n\n\t/// @dev emit when provider recovered ipfs storage\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount ipfs storage amount\n\tevent ProviderRecovered(address provider, bytes32 account, uint256 amount);\n\n\t/// @dev allocate user's normal resource balance\n\t/// @param provider provider address\n\t/// @param amount resource amount\n\t/// @param expiration ipfs expiration\n\tfunction allocateProvider(address provider, uint256 amount, uint256 expiration) external;\n\n\t/// @dev provider drip resource to account directly\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount ipfs storage amount\n\t/// @param expiration ipfs expiration\n\tfunction drip(address provider, bytes32 account, uint256 amount, uint256 expiration) external;\n\n\t/// @dev allocate user's resource balance\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount ipfs storage amount\n\t/// @param expiration ipfs expiration\n\tfunction paymentAllocate(address provider, bytes32 account, uint256 amount, uint256 expiration) external;\n\n\t/// @dev recover provider storage\n\t/// @param provider provider address\n\t/// @param account user account\n\tfunction recoverStorage(address provider, bytes32 account) external;\n\n\t/// @dev return whether ipfs storage is expired for the provider\n\t/// @param provider provider address\n\t/// @return whether ipfs storage is expired for the provider\n\tfunction isProviderExpired(address provider) external view returns (bool);\n\n\t/// @dev return ipfs storage start time for the provider\n\t/// @param provider provider address\n\t/// @return start time for the provider\n\tfunction providerStartTime(address provider) external view returns (uint256);\n\n\t/// @dev return total expiration time for the provider\n\t/// @param provider provider address\n\t/// @return total expiration time for the provider\n\tfunction providerExpiration(address provider) external view returns (uint256);\n\n\t/// @dev return available expiration time for the provider\n\t/// @param provider provider address\n\t/// @return available expiration time for the provider\n\tfunction providerAvailableExpiration(address provider) external view returns (uint256);\n\n\t/// @dev return when the provider will expire\n\t/// @param provider provider address\n\t/// @return when the provider will expire\n\tfunction providerExpiredAt(address provider) external view returns (uint256);\n\n\t/// @dev return ipfs storage amount for the provider\n\t/// @param provider provider address\n\t/// @return ipfs storage amount for the provider\n\tfunction providerBalanceOf(address provider) external view returns (uint256);\n\n\t/// @dev return whether ipfs storage is expired for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return whether ipfs storage is expired for the account\n\tfunction isExpired(address provider, bytes32 account) external view returns (bool);\n\n\t/// @dev return available expiration time for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return available expiration time for the account\n\tfunction availableExpiration(address provider, bytes32 account) external view returns (uint256);\n\n\t/// @dev return when the account will expire\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return when the account will expire\n\tfunction expiredAt(address provider, bytes32 account) external view returns (uint256);\n\n\t/// @dev return ipfs storage start time for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return start time for the account\n\tfunction startTime(address provider, bytes32 account) external view returns (uint256);\n\n\t/// @dev return total expiration time for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return total expiration time for the account\n\tfunction expiration(address provider, bytes32 account) external view returns (uint256);\n\n\t/// @dev return ipfs storage amount for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return ipfs storage amount for the account\n\tfunction balanceOf(address provider, bytes32 account) external view returns (uint256);\n}\n"
    },
    "contracts/resources/interfaces/IResourcePriceAdaptor.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '../../libraries/ResourceData.sol';\n\n/// @author Alexandas\n/// @dev resource adpator interface\ninterface IResourcePriceAdaptor {\n\tstruct PriceAdaptor {\n\t\tResourceData.ResourceType resourceType;\n\t\tuint256 price;\n\t}\n\n\t/// @dev emit when index block updated\n\t/// @param provider provider address\n\t/// @param priceIndexBlock price index block\n\tevent PriceIndexBlockUpdated(address provider, uint256 priceIndexBlock);\n\n\t/// @dev emit when price updated\n\t/// @param provider provider address\n\t/// @param adaptors price adaptors\n\tevent PriceAdaptorsUpdated(address provider, PriceAdaptor[] adaptors);\n\n\t/// @dev get price for resource at a specific block\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param priceIndexBlock block number\n\t/// @return price for resource at a specific block\n\tfunction priceAt(address provider, ResourceData.ResourceType resourceType, uint256 priceIndexBlock) external view returns (uint256);\n\n\t/// @dev get value for `amount` resource at a specific block\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param amount resource amount\n\t/// @param priceIndexBlock block number\n\t/// @return token value in resource decimals(18)\n\tfunction getValueAt(\n\t\taddress provider,\n\t\tResourceData.ResourceType resourceType,\n\t\tuint256 amount,\n\t\tuint256 priceIndexBlock\n\t) external view returns (uint256);\n\n\t/// @dev get amount resource with value at a specific block\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param value token value\n\t/// @param priceIndexBlock block numer\n\t/// @return resource amount\n\tfunction getAmountAt(\n\t\taddress provider,\n\t\tResourceData.ResourceType resourceType,\n\t\tuint256 value,\n\t\tuint256 priceIndexBlock\n\t) external view returns (uint256);\n\n\t/// @dev return resource price\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @return resource price\n\tfunction priceOf(address provider, ResourceData.ResourceType resourceType) external view returns (uint256);\n\n\t/// @dev return value of amount resource\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param amount resource amount\n\t/// @return token value in resource decimals(18)\n\tfunction getValueOf(address provider, ResourceData.ResourceType resourceType, uint256 amount) external view returns (uint256);\n\n\t/// @dev return resource amount with value\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param value token value in resource decimals(18)\n\t/// @return resource amount\n\tfunction getAmountOf(address provider, ResourceData.ResourceType resourceType, uint256 value) external view returns (uint256);\n\n}\n"
    },
    "contracts/libraries/ResourceData.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\nimport '@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol';\n\n/// @author Alexandas\n/// @dev resource data library\nlibrary ResourceData {\n\tusing SafeMathUpgradeable for uint256;\n\n\tenum ResourceType {\n\t\tNull,\n\t\tBuildingTime,\n\t\tBandwidth,\n\t\tARStorage,\n\t\tIPFSStorage\n\t}\n\n\tstruct ValuePayload {\n\t\tResourceData.ResourceType resourceType;\n\t\tuint256[] values;\n\t}\n\n\tstruct AmountPayload {\n\t\tResourceData.ResourceType resourceType;\n\t\tuint256[] amounts;\n\t}\n\n\tstruct ValuePayloads {\n\t\tResourceData.ValuePayload[] payloads;\n\t}\n\n\tfunction convertSourceChainPayloads(ValuePayloads memory valuePayloads, uint256 dstAmount)\n\t\tinternal\n\t\tpure\n\t\treturns (ResourceData.ValuePayload[] memory newPayloads)\n\t{\n\t\tResourceData.ValuePayload[] memory payloads = valuePayloads.payloads;\n\t\trequire(payloads.length > 0, 'ResourceData: invalid payload length');\n\t\tuint256 total = totalValue(payloads);\n\t\trequire(total > 0, 'ResourceData: zero total value');\n\t\tfor (uint256 i = 0; i < payloads.length; i++) {\n\t\t\trequire(payloads[i].values.length > 0, 'ResourceData: invalid value length');\n\t\t\tfor (uint256 j = 0; j < payloads[i].values.length; j++) {\n\t\t\t\tpayloads[i].values[j] = payloads[i].values[j].mul(dstAmount).div(total);\n\t\t\t}\n\t\t}\n\t\treturn payloads;\n\t}\n\n\t/// @dev payment payload total value\n\t/// @param payloads payment payloads\n\t/// @return value total value\n\tfunction totalValue(ResourceData.ValuePayload[] memory payloads) internal pure returns (uint256 value) {\n\t\trequire(payloads.length > 0, 'ResourceData: invalid payloads length');\n\t\tfor (uint256 i = 0; i < payloads.length; i++) {\n\t\t\tfor (uint256 j = 0; j < payloads[i].values.length; j++) {\n\t\t\t\tvalue = value.add(payloads[i].values[j]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/// @dev match token amount to resource decimals\n\t/// @param token token contract address\n\t/// @param value token amount with resource decimals\n\t/// @return resource value\n\tfunction matchTokenToResource(IERC20Upgradeable token, uint256 value) internal view returns (uint256) {\n\t\tuint256 _tokenDecimals = tokenDecimals(token);\n\t\tuint256 _resourceDecimals = decimals();\n\t\tif (_tokenDecimals <= _resourceDecimals) {\n\t\t\treturn value.mul(10**(_resourceDecimals.sub(_tokenDecimals)));\n\t\t}\n\t\treturn value.div(10**(_tokenDecimals.sub(_resourceDecimals)));\n\t}\n\n\t/// @dev match value to token decimals\n\t/// @param token token contract address\n\t/// @param value resource value\n\t/// @return token value\n\tfunction matchResourceToToken(IERC20Upgradeable token, uint256 value) internal view returns (uint256) {\n\t\tuint256 _tokenDecimals = tokenDecimals(token);\n\t\tuint256 _resourceDecimals = decimals();\n\t\tif (_tokenDecimals <= _resourceDecimals) {\n\t\t\treturn value.div(10**(_resourceDecimals.sub(_tokenDecimals)));\n\t\t}\n\t\treturn value.mul(10**(_tokenDecimals.sub(_resourceDecimals)));\n\t}\n\n\t/// @dev return resource decimals\n\t/// @return resource decimals\n\tfunction decimals() internal pure returns (uint256) {\n\t\treturn 18;\n\t}\n\n\t/// @dev return token decimals\n\t/// @return token decimals\n\tfunction tokenDecimals(IERC20Upgradeable token) internal view returns (uint256) {\n\t\t// keccak256(bytes4('decimals()'))\n\t\t(bool success, bytes memory data) = address(token).staticcall(hex'313ce567');\n\t\trequire(success, 'ResourceData: invalid token');\n\t\treturn abi.decode(data, (uint256));\n\t}\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    function __Pausable_init() internal onlyInitializing {\n        __Pausable_init_unchained();\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n        _paused = false;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        require(!paused(), \"Pausable: paused\");\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        require(paused(), \"Pausable: not paused\");\n        _;\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
    },
    "contracts/payments/SrcChainPayment.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol';\n\nimport '../interfaces/IMessageSender.sol';\nimport '../libraries/ResourceData.sol';\nimport '../access/OwnerWithdrawable.sol';\nimport '../access/Pauser.sol';\n\n/// @author Alexandas\n/// @dev source chain payment contract\ncontract SrcChainPayment is ReentrancyGuardUpgradeable, Pauser, OwnerWithdrawable {\n\tusing SafeMathUpgradeable for uint256;\n\tusing SafeERC20Upgradeable for IERC20Upgradeable;\n\n\t/// @dev return token contract address\n\tIERC20Upgradeable public token;\n\n\t/// @dev message sender on src chain\n\tIMessageSender public messageSender;\n\n\t/// @dev emit when token updated\n\t/// @param token token address\n\tevent TokenUpdated(IERC20Upgradeable token);\n\n\t/// @dev emit when message sender updated\n\t/// @param messageSender messageSender address\n\tevent MessageSenderUpdated(IMessageSender messageSender);\n\n\t/// @dev emit when user paid on src chain\n\t/// @param provider provider address\n\t/// @param nonce nonce\n\t/// @param account sender\n\t/// @param payloads payment payloads\n\t/// @param maxSlippage maxSlippage in cBridge\n\tevent Paid(address provider, uint64 nonce, bytes32 account, ResourceData.ValuePayload[] payloads, uint32 maxSlippage);\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param pauser contract pauser\n\t/// @param messageSender messageSender address\n\t/// @param token token address\n\tfunction initialize(\n\t\taddress owner,\n\t\taddress pauser,\n\t\tIMessageSender messageSender,\n\t\tIERC20Upgradeable token\n\t) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Pauser(pauser);\n\t\t__Init_Message_Sender(messageSender);\n\t\t__Init_Token(token);\n\t}\n\n\t/// @dev initialize message sender\n\t/// @param _messageSender messageSender address\n\tfunction __Init_Message_Sender(IMessageSender _messageSender) internal onlyInitializing {\n\t\t_setMessageSender(_messageSender);\n\t}\n\n\tfunction __Init_Token(IERC20Upgradeable _token) internal onlyInitializing {\n\t\t_setToken(_token);\n\t}\n\n\t/// @dev pay from source chain\n\t/// @param provider provider address\n\t/// @param nonce nonce\n\t/// @param account sender\n\t/// @param payloads payment payloads\n\t/// @param maxSlippage maxSlippage in cBridge\n\t/// @return transferId token transfer id in cBridge\n\tfunction pay(\n\t\taddress provider,\n\t\tuint64 nonce,\n\t\tbytes32 account,\n\t\tResourceData.ValuePayload[] memory payloads,\n\t\tuint32 maxSlippage\n\t) external payable whenNotPaused nonReentrant returns (bytes32 transferId) {\n\t\tuint256 value = ResourceData.totalValue(payloads);\n\t\tvalue = ResourceData.matchResourceToToken(token, value);\n\t\ttoken.safeTransferFrom(msg.sender, address(this), value);\n\t\ttoken.safeApprove(address(messageSender), value);\n\t\ttransferId = messageSender.sendMessageWithTransfer{ value: msg.value }(\n\t\t\taddress(token),\n\t\t\tvalue,\n\t\t\tnonce,\n\t\t\tmaxSlippage,\n\t\t\tencodeMessage(provider, nonce, account, payloads),\n\t\t\tMsgDataTypes.BridgeSendType.Liquidity\n\t\t);\n\t\ttoken.safeApprove(address(messageSender), 0);\n\n\t\temit Paid(provider, nonce, account, payloads, maxSlippage);\n\t}\n\n\t/// @dev update message sender\n\t/// @param _messageSender message sender address\n\tfunction setMessageSender(IMessageSender _messageSender) external onlyOwner {\n\t\t_setMessageSender(_messageSender);\n\t}\n\n\tfunction _setMessageSender(IMessageSender _messageSender) internal {\n\t\trequire(address(_messageSender) != address(0), 'SrcChainPayment: zero address');\n\t\tmessageSender = _messageSender;\n\t\temit MessageSenderUpdated(_messageSender);\n\t}\n\n\t/// @dev update token\n\t/// @param _token token address\n\tfunction setToken(IERC20Upgradeable _token) external onlyOwner {\n\t\t_setToken(_token);\n\t}\n\n\tfunction _setToken(IERC20Upgradeable _token) internal {\n\t\trequire(address(_token) != address(0), 'SrcChainPayment: zero address');\n\t\ttoken = _token;\n\t\temit TokenUpdated(token);\n\t}\n\n\t/// @dev calculate message fee\n\t/// @param provider provider address\n\t/// @param nonce nonce\n\t/// @param account user account\n\t/// @param payloads payment payloads\n\t/// @return value message fee\n\tfunction calcFee(\n\t\taddress provider,\n\t\tuint64 nonce,\n\t\tbytes32 account,\n\t\tResourceData.ValuePayload[] memory payloads\n\t) public view returns (uint256 value) {\n\t\treturn messageSender.calcFee(encodeMessage(provider, nonce, account, payloads));\n\t}\n\n\t/// @dev encode payment message\n\t/// @param provider provider address\n\t/// @param nonce nonce\n\t/// @param account user account\n\t/// @param payloads payment payloads\n\t/// @return message message bytes\n\tfunction encodeMessage(\n\t\taddress provider,\n\t\tuint64 nonce,\n\t\tbytes32 account,\n\t\tResourceData.ValuePayload[] memory payloads\n\t) public pure returns (bytes memory) {\n\t\treturn abi.encode(provider, nonce, account, payloads);\n\t}\n}\n"
    },
    "contracts/interfaces/IMessageSender.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport 'sgn-v2-contracts/contracts/message/libraries/MsgDataTypes.sol';\n\ninterface IMessageSender {\n\t/// @dev emit when src chain payment address updated\n\t/// @param payment payment address\n\tevent SrcChainPaymentUpdated(address payment);\n\n\t/// @dev emit when src chain messageBus address updated\n\t/// @param messageBus messageBus address\n\tevent MessageBusUpdated(address messageBus);\n\n\t/// @dev emit when dst chain receiver address updated\n\t/// @param receiver receiver address\n\tevent ReceiverUpdated(address receiver);\n\n\t/// @dev emit when dst chain updated\n\t/// @param dstChainId dst chainId\n\tevent DstChainIdUpdated(uint64 dstChainId);\n\n\t/// @dev emit when transfer refund\n\t/// @param token token address\n\t/// @param amount token amount\n\t/// @param message sender's message\n\t/// @param executor executor address\n\tevent MessageWithTransferRefund(address token, uint256 amount, bytes message, address executor);\n\n\t/// @dev dst chain receiver\n\tfunction receiver() external view returns (address);\n\n\t/// @dev dst chain chainId\n\tfunction dstChainId() external view returns (uint64);\n\n\t/// @dev calculate message fee\n\tfunction calcFee(bytes memory message) external view returns (uint256);\n\n\t/// @dev message id for Message bus in sgn\n\tfunction messageId(\n\t\tMsgDataTypes.RouteInfo calldata route,\n\t\tuint64 dstChainId,\n\t\tbytes calldata message\n\t) external view returns (bytes32);\n\n\t/// @dev send message with transfer to dst chain\n\t/// @param token pay token\n\t/// @param amount token amount\n\t/// @param nonce nonce\n\t/// @param maxSlippage max slippage for cBridge in sgn\n\t/// @param message message for dst chain\n\t/// @param bridgeSendType bridge send type for cBridge\n\t/// @return messageId message id for messageBus in sgn\n\tfunction sendMessageWithTransfer(\n\t\taddress token,\n\t\tuint256 amount,\n\t\tuint64 nonce,\n\t\tuint32 maxSlippage,\n\t\tbytes memory message,\n\t\tMsgDataTypes.BridgeSendType bridgeSendType\n\t) external payable returns (bytes32);\n}\n"
    },
    "sgn-v2-contracts/contracts/message/libraries/MsgDataTypes.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity 0.8.9;\n\nlibrary MsgDataTypes {\n    // bridge operation type at the sender side (src chain)\n    enum BridgeSendType {\n        Null,\n        Liquidity,\n        PegDeposit,\n        PegBurn,\n        PegV2Deposit,\n        PegV2Burn,\n        PegV2BurnFrom\n    }\n\n    // bridge operation type at the receiver side (dst chain)\n    enum TransferType {\n        Null,\n        LqRelay, // relay through liquidity bridge\n        LqWithdraw, // withdraw from liquidity bridge\n        PegMint, // mint through pegged token bridge\n        PegWithdraw, // withdraw from original token vault\n        PegV2Mint, // mint through pegged token bridge v2\n        PegV2Withdraw // withdraw from original token vault v2\n    }\n\n    enum MsgType {\n        MessageWithTransfer,\n        MessageOnly\n    }\n\n    enum TxStatus {\n        Null,\n        Success,\n        Fail,\n        Fallback,\n        Pending // transient state within a transaction\n    }\n\n    struct TransferInfo {\n        TransferType t;\n        address sender;\n        address receiver;\n        address token;\n        uint256 amount;\n        uint64 wdseq; // only needed for LqWithdraw (refund)\n        uint64 srcChainId;\n        bytes32 refId;\n        bytes32 srcTxHash; // src chain msg tx hash\n    }\n\n    struct RouteInfo {\n        address sender;\n        address receiver;\n        uint64 srcChainId;\n        bytes32 srcTxHash; // src chain msg tx hash\n    }\n\n    struct MsgWithTransferExecutionParams {\n        bytes message;\n        TransferInfo transfer;\n        bytes[] sigs;\n        address[] signers;\n        uint256[] powers;\n    }\n\n    struct BridgeTransferParams {\n        bytes request;\n        bytes[] sigs;\n        address[] signers;\n        uint256[] powers;\n    }\n}\n"
    },
    "contracts/wallets/Billing.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol';\n\nimport '../libraries/ResourceData.sol';\nimport '../govers/RouterWrapper.sol';\nimport '../access/OwnerWithdrawable.sol';\n\n/// @author Alexandas\n/// @dev Billing contract\ncontract Billing is IBilling, OwnerWithdrawable, EIP712Upgradeable, ReentrancyGuardUpgradeable, RouterWrapper {\n\tusing SafeMathUpgradeable for uint256;\n\tusing SafeERC20Upgradeable for IERC20Upgradeable;\n\n\t/// @dev keccak256(\"Billing(address provider,bytes32 account,bytes bills,uint256 timeout,uint64 nonce)\")\n\tbytes32 public override billingTypesHash;\n\n\t/// @dev provider nonces for account\n\tmapping(address => mapping(bytes32 => mapping(uint64 => bool))) internal nonces;\n\n\t/// @dev provider balances\n\tmapping(address => uint256) internal balances;\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param name EIP712 name\n\t/// @param version EIP712 version\n\t/// @param router router contract address\n\tfunction initialize(\n\t\taddress owner,\n\t\tstring memory name,\n\t\tstring memory version,\n\t\tstring memory billingTypes,\n\t\tIRouter router\n\t) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__EIP712_init(name, version);\n\t\t__Init_Billing_Typed_Hash(billingTypes);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev initialize billing types hash\n\t/// @param types billing types\n\tfunction __Init_Billing_Typed_Hash(string memory types) internal onlyInitializing {\n\t\t_setBillingTypedHash(keccak256(bytes(types)));\n\t}\n\n\t/// @dev spend bills\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param bills billing data\n\t/// @param timeout tx timeout\n\t/// @param nonce billing nonce\n\t/// @param signature billing signature\n\t/// @return fee billing fee\n\tfunction spend(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tbytes memory bills,\n\t\tuint256 timeout,\n\t\tuint64 nonce,\n\t\tbytes memory signature\n\t) external nonReentrant onlyFundPool returns (uint256 fee) {\n\t\trequire(nonce > 0, 'Billing: invalid nonce');\n\t\trequire(timeout > block.timestamp, 'Billing: tx expires');\n\t\trequire(!nonces[provider][account][nonce], 'Billing: nonce exists');\n\t\tbytes32 hash = hashTypedDataV4ForBills(provider, account, bills, timeout, nonce);\n\t\trequire(router.ProviderRegistry().isValidSignature(provider, hash, signature), 'Billing: invalid signature');\n\t\tfee = _spend(provider, account, bills, nonce);\n\n\t\temit Billing(provider, account, bills, fee, nonce);\n\t}\n\n\tfunction _spend(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tbytes memory bills,\n\t\tuint64 nonce\n\t) internal returns (uint256 fee) {\n\t\tIERC20Upgradeable token = router.Token();\n\t\tfee = _validateBills(provider, bills);\n\t\tif(fee > 0) {\n\t\t\tfee = ResourceData.matchResourceToToken(token, fee);\n\t\t\tbalances[provider] = balances[provider].add(fee);\n\t\t}\n\t\tnonces[provider][account][nonce] = true;\n\t}\n\n\tfunction _validateBills(address provider, bytes memory data) internal view returns (uint256 value) {\n\t\tBill[] memory bills = abi.decode(data, (Bill[]));\n\t\tif (bills.length > 0) {\n\t\t\tfor (uint256 i = 0; i < bills.length; i++) {\n\t\t\t\tBill memory bill = bills[i];\n\t\t\t\trequire(bill.entries.length > 0, 'Billing: empty bill entry');\n\t\t\t\tfor (uint256 j = 0; j < bill.entries.length; j++) {\n\t\t\t\t\tBillEntry memory entry = bill.entries[j];\n\t\t\t\t\tuint256 billing = router.ResourcePriceAdaptor().getValueAt(provider, entry.resourceType, entry.amount, bill.indexBlock);\n\t\t\t\t\tvalue = value.add(billing);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/// @dev return bill fee\n\t/// @param provider provider address\n\t/// @param data bill data\n\t/// @return value bill fee\n\tfunction billFee(address provider, bytes memory data) external view returns (uint256 value) { \n\t\treturn _validateBills(provider, data);\n\t}\n\n\t/// @dev return hash for bills\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param bills user bills\n\t/// @param timeout tx timeout\n\t/// @param nonce nonce\n\t/// @return bills hash\n\tfunction hashBillingTypes(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tbytes memory bills,\n\t\tuint256 timeout,\n\t\tuint64 nonce\n\t) public view returns (bytes32) {\n\t\treturn keccak256(abi.encode(billingTypesHash, provider, account, keccak256(bills), timeout, nonce));\n\t}\n\n\t/// @dev return hash typed data v4 for sign bills\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param bills user bills\n\t/// @param timeout tx timeout\n\t/// @param nonce nonce\n\t/// @return bills hash typed data v4\n\tfunction hashTypedDataV4ForBills(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tbytes memory bills,\n\t\tuint256 timeout,\n\t\tuint64 nonce\n\t) public view returns (bytes32) {\n\t\treturn _hashTypedDataV4(hashBillingTypes(provider, account, bills, timeout, nonce));\n\t}\n\n\tfunction _setBillingTypedHash(bytes32 hash) internal {\n\t\tbillingTypesHash = hash;\n\t\temit BillingTypesHashUpdated(hash);\n\t}\n\n\t/// @dev return balance of provider\n\t/// @param provider provider address\n\t/// @return balance of provider\n\tfunction balanceOf(address provider) public view override returns (uint256) {\n\t\trequire(router.ProviderRegistry().isProvider(provider), 'Billing: nonexistent provider');\n\t\treturn balances[provider];\n\t}\n\n\t/// @dev provider nonces for account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param nonce nonce\n\t/// @return whether nonce exists\n\tfunction nonceExists(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint64 nonce\n\t) public view override returns (bool) {\n\t\trequire(router.ProviderController().accountExists(provider, account), 'Billing: nonexistent provider');\n\t\treturn nonces[provider][account][nonce];\n\t}\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n    /* solhint-disable var-name-mixedcase */\n    bytes32 private _HASHED_NAME;\n    bytes32 private _HASHED_VERSION;\n    bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n    /* solhint-enable var-name-mixedcase */\n\n    /**\n     * @dev Initializes the domain separator and parameter caches.\n     *\n     * The meaning of `name` and `version` is specified in\n     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n     *\n     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n     * - `version`: the current major version of the signing domain.\n     *\n     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n     * contract upgrade].\n     */\n    function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n        __EIP712_init_unchained(name, version);\n    }\n\n    function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n        bytes32 hashedName = keccak256(bytes(name));\n        bytes32 hashedVersion = keccak256(bytes(version));\n        _HASHED_NAME = hashedName;\n        _HASHED_VERSION = hashedVersion;\n    }\n\n    /**\n     * @dev Returns the domain separator for the current chain.\n     */\n    function _domainSeparatorV4() internal view returns (bytes32) {\n        return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n    }\n\n    function _buildDomainSeparator(\n        bytes32 typeHash,\n        bytes32 nameHash,\n        bytes32 versionHash\n    ) private view returns (bytes32) {\n        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n    }\n\n    /**\n     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n     * function returns the hash of the fully encoded EIP712 message for this domain.\n     *\n     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n     *\n     * ```solidity\n     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n     *     keccak256(\"Mail(address to,string contents)\"),\n     *     mailTo,\n     *     keccak256(bytes(mailContents))\n     * )));\n     * address signer = ECDSA.recover(digest, signature);\n     * ```\n     */\n    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n        return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n    }\n\n    /**\n     * @dev The hash of the name parameter for the EIP712 domain.\n     *\n     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n     * are a concern.\n     */\n    function _EIP712NameHash() internal virtual view returns (bytes32) {\n        return _HASHED_NAME;\n    }\n\n    /**\n     * @dev The hash of the version parameter for the EIP712 domain.\n     *\n     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n     * are a concern.\n     */\n    function _EIP712VersionHash() internal virtual view returns (bytes32) {\n        return _HASHED_VERSION;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        } else if (error == RecoverError.InvalidSignatureV) {\n            revert(\"ECDSA: invalid signature 'v' value\");\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n        // Check the signature length\n        // - case 65: r,s,v signature (standard)\n        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else if (signature.length == 64) {\n            bytes32 r;\n            bytes32 vs;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly {\n                r := mload(add(signature, 0x20))\n                vs := mload(add(signature, 0x40))\n            }\n            return tryRecover(hash, r, vs);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength);\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address, RecoverError) {\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\n        return tryRecover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address, RecoverError) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS);\n        }\n        if (v != 27 && v != 28) {\n            return (address(0), RecoverError.InvalidSignatureV);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature);\n        }\n\n        return (signer, RecoverError.NoError);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n    }\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n    bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return \"0x00\";\n        }\n        uint256 temp = value;\n        uint256 length = 0;\n        while (temp != 0) {\n            length++;\n            temp >>= 8;\n        }\n        return toHexString(value, length);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _HEX_SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n}\n"
    },
    "contracts/resources/ResourcePriceAdaptor.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol';\n\nimport '../govers/RouterWrapper.sol';\n\n/// @author Alexandas\n/// @dev Resource price adaptor contract\ncontract ResourcePriceAdaptor is IResourcePriceAdaptor, RouterWrapper, OwnableUpgradeable {\n\tusing SafeMathUpgradeable for uint256;\n\n\t/// @dev return current price index blocks\n\tmapping(address => uint256) public priceIndexBlocks;\n\n\t/// @dev return all resource price\n\tmapping(address => mapping(ResourceData.ResourceType => mapping(uint256 => uint256))) internal prices;\n\n\tmodifier ValidateType(ResourceData.ResourceType resourceType) {\n\t\trequire(\n\t\t\tresourceType == ResourceData.ResourceType.BuildingTime ||\n\t\t\tresourceType == ResourceData.ResourceType.Bandwidth ||\n\t\t\tresourceType == ResourceData.ResourceType.ARStorage ||\n\t\t\tresourceType == ResourceData.ResourceType.IPFSStorage, \n\t\t\t'ResourcePriceAdaptor: invalid resource type'\n\t\t);\n\t\t_;\n\t}\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param router router contract address\n\tfunction initialize(address owner, IRouter router) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev update price adaptors\n\t/// @param adaptors price adaptors\n\tfunction setPriceAdaptors(PriceAdaptor[] memory adaptors) external onlyProvider {\n\t\t_setPriceAdaptors(msg.sender, adaptors);\n\t\t_setPriceIndexBlock(msg.sender, block.number);\n\t}\n\n\tfunction _setPriceAdaptors(address provider, PriceAdaptor[] memory adaptors) internal {\n\t\trequire(adaptors.length > 0, 'ResourcePriceAdaptor: invalid pricers');\n\t\tfor (uint256 i = 0; i < adaptors.length; i++) {\n\t\t\tuint256 price = adaptors[i].price;\n\t\t\trequire(price > 0, 'ResourcePriceAdaptor: invalid price');\n\t\t\tResourceData.ResourceType resourceType = adaptors[i].resourceType;\n\t\t\trequire(resourceType != ResourceData.ResourceType.Null, 'ResourcePriceAdaptor: invalid resource type');\n\t\t\tprices[provider][resourceType][block.number] = price;\n\t\t}\n\t\temit PriceAdaptorsUpdated(provider, adaptors);\n\t}\n\n\tfunction _setPriceIndexBlock(address provider, uint256 indexBlock) internal {\n\t\tpriceIndexBlocks[provider] = indexBlock;\n\t\temit PriceIndexBlockUpdated(provider, indexBlock);\n\t}\n\n\t/// @dev get price for resource at a specific block\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param priceIndexBlock block number\n\t/// @return price for resource at a specific block\n\tfunction priceAt(address provider, ResourceData.ResourceType resourceType, uint256 priceIndexBlock) public view override ValidateType(resourceType) returns (uint256) {\n\t\trequire(router.ProviderRegistry().isProvider(provider), 'ResourcePriceAdaptor: nonexistent provider');\n\t\trequire(prices[provider][resourceType][priceIndexBlock] != 0, 'ResourcePriceAdaptor: zero price');\n\t\treturn prices[provider][resourceType][priceIndexBlock];\n\t}\n\n\t/// @dev get value for `amount` resource at a specific block\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param amount resource amount\n\t/// @param priceIndexBlock block number\n\t/// @return token value in resource decimals(18)\n\tfunction getValueAt(\n\t\taddress provider,\n\t\tResourceData.ResourceType resourceType,\n\t\tuint256 amount,\n\t\tuint256 priceIndexBlock\n\t) public view override returns (uint256) {\n\t\treturn priceAt(provider, resourceType, priceIndexBlock).mul(amount);\n\t}\n\n\t/// @dev get amount resource with value at a specific block\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param value token value\n\t/// @param priceIndexBlock block numer\n\t/// @return resource amount\n\tfunction getAmountAt(\n\t\taddress provider,\n\t\tResourceData.ResourceType resourceType,\n\t\tuint256 value,\n\t\tuint256 priceIndexBlock\n\t) public view override returns (uint256) {\n\t\treturn value.div(priceAt(provider, resourceType, priceIndexBlock));\n\t}\n\n\t/// @dev return resource price\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @return resource price\n\tfunction priceOf(address provider, ResourceData.ResourceType resourceType) public view override returns (uint256) {\n\t\treturn priceAt(provider, resourceType, priceIndexBlocks[provider]);\n\t}\n\n\t/// @dev return value of amount resource\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param amount resource amount\n\t/// @return token value in resource decimals(18)\n\tfunction getValueOf(address provider, ResourceData.ResourceType resourceType, uint256 amount) public view override returns (uint256) {\n\t\treturn priceOf(provider, resourceType).mul(amount);\n\t}\n\n\t/// @dev return resource amount with value\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param value token value in resource decimals(18)\n\t/// @return resource amount\n\tfunction getAmountOf(address provider, ResourceData.ResourceType resourceType, uint256 value) public view override returns (uint256) {\n\t\treturn value.div(priceOf(provider, resourceType));\n\t}\n\n}\n"
    },
    "contracts/resources/controllers/NormalResourceController.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol';\nimport '../interfaces/INormalResourceController.sol';\nimport '../../govers/RouterWrapper.sol';\n\n/// @author Alexandas\n/// @dev Normal resource controller\nabstract contract NormalResourceController is INormalResourceController, RouterWrapper, OwnableUpgradeable {\n\tusing SafeMathUpgradeable for uint256;\n\n\t/// @dev provider balances\n\tmapping(address => uint256) internal providerBalances;\n\n\t/// @dev resource balances for account in provider\n\tmapping(address => mapping(bytes32 => uint256)) internal balances;\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param router router contract\n\tfunction __Init_Normal_Resource_Controller(address owner, IRouter router) internal onlyInitializing {\n\t\t_transferOwnership(owner);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev allocate resource for the provider\n\t/// @param provider provider address\n\t/// @param amount resource amount\n\tfunction allocateProvider(address provider, uint256 amount) external override onlyGovernance {\n\t\t_allocateProivder(provider, amount);\n\t}\n\n\t/// @dev provider drip resource to account directly\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount resource amount\n\tfunction drip(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount\n\t) external override onlyProviderController {\n\t\t_allocateAccount(provider, account, amount);\n\t}\n\n\t/// @dev allocate user's resource balance\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount resource amount\n\tfunction paymentAllocate(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount\n\t) external override onlyDstChainPayment {\n\t\t_allocateAccount(provider, account, amount);\n\t}\n\n\tfunction _allocateAccount(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount\n\t) internal {\n\t\trequire(providerBalanceOf(provider) >= amount, 'NormalResourceController: insufficient provider balance');\n\t\tbalances[provider][account] = balances[provider][account].add(amount);\n\t\tproviderBalances[provider] = providerBalances[provider].sub(amount);\n\n\t\temit AccountAllocated(provider, account, amount);\n\t}\n\n\tfunction _allocateProivder(address provider, uint256 amount) internal {\n\t\tproviderBalances[provider] = providerBalances[provider].add(amount);\n\n\t\temit ProviderAllocated(provider, amount);\n\t}\n\n\t/// @dev resource balance\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return balance of the account\n\tfunction balanceOf(address provider, bytes32 account) public view override returns (uint256) {\n\t\treturn balances[provider][account];\n\t}\n\n\t/// @dev resource balance\n\t/// @param provider provider address\n\t/// @return balance of the account\n\tfunction providerBalanceOf(address provider) public view override returns (uint256) {\n\t\treturn providerBalances[provider];\n\t}\n}\n"
    },
    "contracts/resources/controllers/normal/BuildingTimeController.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '../NormalResourceController.sol';\n\n/// @author Alexandas\n/// @dev Building time controller controller\ncontract BuildingTimeController is NormalResourceController {\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param router router contract\n\tfunction initialize(\n\t\taddress owner,\n\t\tIRouter router\n\t) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Router(router);\n\t}\n}\n"
    },
    "contracts/resources/controllers/normal/BandwidthController.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '../NormalResourceController.sol';\n\n/// @author Alexandas\n/// @dev Bandwidth controller controller\ncontract BandwidthController is NormalResourceController {\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param router router contract\n\tfunction initialize(\n\t\taddress owner,\n\t\tIRouter router\n\t) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Router(router);\n\t}\n}\n"
    },
    "contracts/govers/Router.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\n\nimport '../interfaces/IRouter.sol';\n\n/// @author Alexandas\n/// @dev Router contract\ncontract Router is IRouter, OwnableUpgradeable {\n\t/// @dev message receiver contract address\n\taddress public override MessageReceiver;\n\n\t/// @dev Governance contract address\n\tIGovernance public override Governance;\n\n\t/// @dev providers contract address\n\tIProviderRegistry public override ProviderRegistry;\n\n\t/// @dev provider controller contract address\n\tIProviderController public override ProviderController;\n\n\t/// @dev token address\n\tIERC20Upgradeable public override Token;\n\n\t/// @dev return building time controller\n\tINormalResourceController public override BuildingTimeController;\n\n\t/// @dev return bandwidth controller\n\tINormalResourceController public override BandwidthController;\n\n\t/// @dev return AR storage controller\n\tINormalResourceController public override ARStorageController;\n\n\t/// @dev return ipfs storage controller\n\tIIPFSStorageController public override IPFSStorageController;\n\n\t/// @dev return resource price adaptor contract address\n\tIResourcePriceAdaptor public override ResourcePriceAdaptor;\n\n\t/// @dev dst chain payment contract address\n\tIDstChainPayment public override DstChainPayment;\n\n\t/// @dev billing contract address\n\tIBilling public override Billing;\n\n\t/// @dev fund pool contract address\n\tIFundPool public override FundPool;\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\tfunction initialize(address owner) external initializer {\n\t\t_transferOwnership(owner);\n\t}\n\n\t/// @dev set messageReceiver contract address\n\t/// @param _messageReceiver message receiver contract address\n\tfunction setMessageReceiver(address _messageReceiver) external onlyOwner {\n\t\trequire(address(_messageReceiver) != address(0), 'Router: zero address');\n\t\tMessageReceiver = _messageReceiver;\n\t\temit MessageReceiverUpdated(_messageReceiver);\n\t}\n\n\t/// @dev update GoverDrip contract address\n\t/// @param _governance governance contract address\n\tfunction setGovernance(IGovernance _governance) external onlyOwner {\n\t\trequire(address(_governance) != address(0), 'Router: zero address');\n\t\tGovernance = _governance;\n\t\temit GovernanceUpdated(_governance);\n\t}\n\n\t/// @dev update provider registry contract\n\t/// @param _providerRegistry provider registry contract address\n\tfunction setProviderRegistry(IProviderRegistry _providerRegistry) external onlyOwner {\n\t\trequire(address(_providerRegistry) != address(0), 'Router: zero address');\n\t\tProviderRegistry = _providerRegistry;\n\t\temit ProviderRegistryUpdated(_providerRegistry);\n\t}\n\n\t/// @dev update provider controller contract address\n\t/// @param _providerController provider controller contract address\n\tfunction setProviderController(IProviderController _providerController) external onlyOwner {\n\t\trequire(address(_providerController) != address(0), 'Router: zero address');\n\t\tProviderController = _providerController;\n\t\temit ProviderControllerUpdated(_providerController);\n\t}\n\n\t/// @dev update token address\n\t/// @param _token token address\n\tfunction setToken(IERC20Upgradeable _token) external onlyOwner {\n\t\trequire(address(_token) != address(0), 'Router: zero address');\n\t\tToken = _token;\n\t\temit TokenUpdated(_token);\n\t}\n\n\t/// @dev update building time controller contract\n\t/// @param _buildingTimeController building time controller contract\n\tfunction setBuildingTimeController(INormalResourceController _buildingTimeController) external onlyOwner {\n\t\trequire(address(_buildingTimeController) != address(0), 'Router: zero address');\n\t\tBuildingTimeController = _buildingTimeController;\n\t\temit BuildingTimeControllerUpdated(_buildingTimeController);\n\t}\n\n\t/// @dev update bandwidth controller contract\n\t/// @param _bandwidthController bandwidth controller contract\n\tfunction setBandwidthController(INormalResourceController _bandwidthController) external onlyOwner {\n\t\trequire(address(_bandwidthController) != address(0), 'Router: zero address');\n\t\tBandwidthController = _bandwidthController;\n\t\temit BandwidthControllerUpdated(_bandwidthController);\n\t}\n\n\t/// @dev update AR storage controller contract\n\t/// @param _arStorageController AR storage controller contract\n\tfunction setARStorageController(INormalResourceController _arStorageController) external onlyOwner {\n\t\trequire(address(_arStorageController) != address(0), 'Router: zero address');\n\t\tARStorageController = _arStorageController;\n\t\temit ARStorageControllerUpdated(_arStorageController);\n\t}\n\n\t/// @dev update ipfs storage controller contract\n\t/// @param _ipfsStorageController IPFS storage controller contract\n\tfunction setIPFSStorageController(IIPFSStorageController _ipfsStorageController) external onlyOwner {\n\t\trequire(address(_ipfsStorageController) != address(0), 'Router: zero address');\n\t\tIPFSStorageController = _ipfsStorageController;\n\t\temit IPFSStorageControllerUpdated(_ipfsStorageController);\n\t}\n\n\t/// @dev update resource adaptor contract\n\t/// @param _resourcePriceAdaptor resource adaptor contract\n\tfunction setResourcePriceAdaptor(IResourcePriceAdaptor _resourcePriceAdaptor) external onlyOwner {\n\t\trequire(address(_resourcePriceAdaptor) != address(0), 'Router: zero address');\n\t\tResourcePriceAdaptor = _resourcePriceAdaptor;\n\t\temit ResourcePriceAdaptorUpdated(_resourcePriceAdaptor);\n\t}\n\n\t/// @dev update dst chain payment contract address\n\t/// @param _dstChainPayment dst chain payment contract address\n\tfunction setDstChainPayment(IDstChainPayment _dstChainPayment) external onlyOwner {\n\t\trequire(address(_dstChainPayment) != address(0), 'Router: zero address');\n\t\tDstChainPayment = _dstChainPayment;\n\t\temit DstChainPaymentUpdated(_dstChainPayment);\n\t}\n\n\t/// @dev update resource adaptor contract\n\t/// @param _billing billing contract\n\tfunction setBilling(IBilling _billing) external onlyOwner {\n\t\trequire(address(_billing) != address(0), 'Router: zero address');\n\t\tBilling = _billing;\n\t\temit BillingUpdated(_billing);\n\t}\n\n\t/// @dev update resource adaptor contract\n\t/// @param _pool fund pool contract\n\tfunction setFundPool(IFundPool _pool) external onlyOwner {\n\t\trequire(address(_pool) != address(0), 'Router: zero address');\n\t\tFundPool = _pool;\n\t\temit FundPoolUpdated(_pool);\n\t}\n}\n"
    },
    "contracts/resources/controllers/IPFSStorageController.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol';\n\nimport '../interfaces/IIPFSStorageController.sol';\nimport '../../govers/RouterWrapper.sol';\n\n/// @author Alexandas\n/// @dev IPFS storage controller\ncontract IPFSStorageController is IIPFSStorageController, RouterWrapper, OwnableUpgradeable {\n\tusing SafeMathUpgradeable for uint256;\n\n\t/// @dev provider storage\n\tmapping(address => Storage) internal providersStorage;\n\n\t/// @dev ipfs storage for account\n\tmapping(address => mapping(bytes32 => Storage)) internal storages;\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param router router contract address\n\tfunction initialize(address owner, IRouter router) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev allocate user's normal resource balance\n\t/// @param provider provider address\n\t/// @param amount resource amount\n\t/// @param expiration ipfs expiration\n\tfunction allocateProvider(\n\t\taddress provider,\n\t\tuint256 amount,\n\t\tuint256 expiration\n\t) external override onlyGovernance {\n\t\t_allocateProivder(provider, amount, expiration);\n\t}\n\n\t/// @dev provider drip resource to account directly\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount ipfs storage amount\n\t/// @param expiration ipfs expiration\n\tfunction drip(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount,\n\t\tuint256 expiration\n\t) external override onlyProviderController {\n\t\t_allocateAccount(provider, account, amount, expiration);\n\t}\n\n\t/// @dev allocate user's resource balance\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount ipfs storage amount\n\t/// @param expiration ipfs expiration\n\tfunction paymentAllocate(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount,\n\t\tuint256 expiration\n\t) external override onlyDstChainPayment {\n\t\t_allocateAccount(provider, account, amount, expiration);\n\t}\n\n\tfunction _allocateAccount(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount,\n\t\tuint256 expiration\n\t) internal {\n\t\trequire(!isProviderExpired(provider), 'IPFSStorageController: provider expired');\n\t\trequire(providerBalanceOf(provider) >= amount, 'IPFSStorageController: insufficient balance for the provider');\n\t\tif (isExpired(provider, account)) {\n\t\t\tif (storages[provider][account].amount > 0) {\n\t\t\t\t_recoverStorage(provider, account);\n\t\t\t}\n\t\t\tstorages[provider][account].startTime = block.timestamp;\n\t\t\tstorages[provider][account].amount = amount;\n\t\t\tstorages[provider][account].expiration = expiration;\n\t\t} else {\n\t\t\tstorages[provider][account].amount = storages[provider][account].amount.add(amount);\n\t\t\tstorages[provider][account].expiration = storages[provider][account].expiration.add(expiration);\n\t\t}\n\t\trequire(providerExpiredAt(provider) >= expiredAt(provider, account), 'IPFSStorageController: expiration overflows');\n\t\tif (amount > 0) {\n\t\t\tprovidersStorage[provider].amount = providersStorage[provider].amount.sub(amount);\n\t\t}\n\t\temit AccountAllocated(provider, account, amount, expiration);\n\t}\n\n\tfunction _allocateProivder(\n\t\taddress provider,\n\t\tuint256 amount,\n\t\tuint256 expiration\n\t) internal {\n\t\tif (isProviderExpired(provider)) {\n\t\t\tprovidersStorage[provider] = Storage({ startTime: block.timestamp, amount: amount, expiration: expiration });\n\t\t} else {\n\t\t\tprovidersStorage[provider].amount = providersStorage[provider].amount.add(amount);\n\t\t\tprovidersStorage[provider].expiration = providersStorage[provider].expiration.add(expiration);\n\t\t}\n\n\t\temit ProviderAllocated(provider, amount, expiration);\n\t}\n\n\t/// @dev recover provider storage\n\t/// @param provider provider address\n\t/// @param account user account\n\tfunction recoverStorage(address provider, bytes32 account) external override {\n\t\t_recoverStorage(provider, account);\n\t}\n\n\tfunction _recoverStorage(address provider, bytes32 account) internal {\n\t\trequire(!isProviderExpired(provider), 'IPFSStorageController: provider expired');\n\t\trequire(isExpired(provider, account), 'IPFSStorageController: account is not expired');\n\t\tuint256 amount = storages[provider][account].amount;\n\t\trequire(amount > 0, 'IPFSStorageController: empty storage to recover');\n\t\tprovidersStorage[provider].amount = providersStorage[provider].amount.add(amount);\n\t\tstorages[provider][account].amount = 0;\n\n\t\temit ProviderRecovered(provider, account, amount);\n\t}\n\n\t/// @dev return whether ipfs storage is expired for the provider\n\t/// @param provider provider address\n\t/// @return whether ipfs storage is expired for the provider\n\tfunction isProviderExpired(address provider) public view override returns (bool) {\n\t\treturn block.timestamp > providerExpiredAt(provider);\n\t}\n\n\t/// @dev return ipfs storage start time for the provider\n\t/// @param provider provider address\n\t/// @return start time for the provider\n\tfunction providerStartTime(address provider) public view override returns (uint256) {\n\t\treturn providersStorage[provider].startTime;\n\t}\n\n\t/// @dev return total expiration time for the provider\n\t/// @param provider provider address\n\t/// @return total expiration time for the provider\n\tfunction providerExpiration(address provider) public view override returns (uint256) {\n\t\treturn providersStorage[provider].expiration;\n\t}\n\n\t/// @dev return available expiration time for the provider\n\t/// @param provider provider address\n\t/// @return available expiration time for the provider\n\tfunction providerAvailableExpiration(address provider) public view override returns (uint256) {\n\t\trequire(!isProviderExpired(provider), 'IPFSStorageController: provider is expired.');\n\t\treturn providerExpiredAt(provider).sub(block.timestamp);\n\t}\n\n\t/// @dev return when the provider will expire\n\t/// @param provider provider address\n\t/// @return when the provider will expire\n\tfunction providerExpiredAt(address provider) public view override returns (uint256) {\n\t\treturn providerStartTime(provider).add(providerExpiration(provider));\n\t}\n\n\t/// @dev return ipfs storage amount for the provider\n\t/// @param provider provider address\n\t/// @return ipfs storage amount for the provider\n\tfunction providerBalanceOf(address provider) public view override returns (uint256) {\n\t\trequire(!isProviderExpired(provider), 'IPFSStorageController: provider is expired.');\n\t\treturn providersStorage[provider].amount;\n\t}\n\n\t/// @dev return whether ipfs storage is expired for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return whether ipfs storage is expired for the account\n\tfunction isExpired(address provider, bytes32 account) public view override returns (bool) {\n\t\treturn block.timestamp > expiredAt(provider, account);\n\t}\n\n\t/// @dev return available expiration time for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return available expiration time for the account\n\tfunction availableExpiration(address provider, bytes32 account) public view override returns (uint256) {\n\t\trequire(!isExpired(provider, account), 'IPFSStorageController: account is expired.');\n\t\treturn expiredAt(provider, account).sub(block.timestamp);\n\t}\n\n\t/// @dev return when the account will expire\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return when the account will expire\n\tfunction expiredAt(address provider, bytes32 account) public view override returns (uint256) {\n\t\treturn startTime(provider, account).add(expiration(provider, account));\n\t}\n\n\t/// @dev return ipfs storage start time for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return start time for the account\n\tfunction startTime(address provider, bytes32 account) public view override returns (uint256) {\n\t\treturn storages[provider][account].startTime;\n\t}\n\n\t/// @dev return total expiration time for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return total expiration time for the account\n\tfunction expiration(address provider, bytes32 account) public view override returns (uint256) {\n\t\treturn storages[provider][account].expiration;\n\t}\n\n\t/// @dev return ipfs storage amount for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return ipfs storage amount for the account\n\tfunction balanceOf(address provider, bytes32 account) public view override returns (uint256) {\n\t\trequire(!isExpired(provider, account), 'IPFSStorageController: account is expired.');\n\t\treturn storages[provider][account].amount;\n\t}\n}\n"
    },
    "contracts/messages/MessageReceiver.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol';\n\nimport 'sgn-v2-contracts/contracts/message/libraries/MsgDataTypes.sol';\n\nimport '../access/OwnerWithdrawable.sol';\nimport '../interfaces/IDstChainPayment.sol';\nimport '../govers/RouterWrapper.sol';\n\n/// @author Alexandas\n/// @dev dst chain message receiver\ncontract MessageReceiver is RouterWrapper, OwnerWithdrawable {\n\tusing SafeMathUpgradeable for uint256;\n\tusing SafeERC20Upgradeable for IERC20Upgradeable;\n\tenum ExecutionStatus {\n\t\tFail,\n\t\tSuccess,\n\t\tRetry\n\t}\n\n\t/// @dev message bus in dst chain\n\taddress public messageBus;\n\n\t/// @dev message executor\n\taddress public executor;\n\n\t/// @dev emit when message bus updated\n\t/// @param messageBus dst chain messageBus in sgn\n\tevent MessageBusUpdated(address messageBus);\n\n\t/// @dev emit when executor changed\n\t/// @param executor executor address\n\tevent ExecutorUpdated(address executor);\n\n\t/// @dev emit when message with transfer executed\n\t/// @param sender message sender address\n\t/// @param token token address\n\t/// @param amount token amount\n\t/// @param srcChainId src chain chainId\n\t/// @param message src chain message\n\t/// @param executor executor address\n\tevent MessageWithTransferExecuted(address sender, IERC20Upgradeable token, uint256 amount, uint64 srcChainId, bytes message, address executor);\n\n\t/// @dev emit message with transfer failed\n\t/// @param sender message sender address\n\t/// @param token token address\n\t/// @param amount token amount\n\t/// @param srcChainId src chain chainId\n\t/// @param message src chain message\n\t/// @param executor executor address\n\t/// @param error error message\n\tevent MessageWithTransferFailed(address sender, IERC20Upgradeable token, uint256 amount, uint64 srcChainId, bytes message, address executor, bytes error);\n\n\t/// @dev emit when message with transfer fallback\n\t/// @param _sender message sender address\n\t/// @param _token token address\n\t/// @param _amount token amount\n\t/// @param _srcChainId src chain chainId\n\t/// @param _message src chain message\n\t/// @param executor executor address\n\tevent MessageWithTransferFallback(address _sender, address _token, uint256 _amount, uint64 _srcChainId, bytes _message, address executor);\n\n\tmodifier onlyMessageBus() {\n\t\trequire(msg.sender == messageBus, 'MessageReceiver: caller is not message bus');\n\t\t_;\n\t}\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy intialize function\n\t/// @param owner contract owner\n\t/// @param _messageBus dst chain message bus\n\t/// @param _executor executor address\n\tfunction initialize(\n\t\taddress owner,\n\t\taddress _messageBus,\n\t\taddress _executor,\n\t\tIRouter router\n\t) external initializer {\n\t\t_transferOwnership(owner);\n\t\t_setMessageBus(_messageBus);\n\t\t_setExecutor(_executor);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev execute message with transfer\n\t/// @param sender message sender address\n\t/// @param token token address\n\t/// @param amount token amount\n\t/// @param srcChainId src chain chainId\n\t/// @param message src chain message\n\t/// @param _executor executor address\n\tfunction executeMessageWithTransfer(\n\t\taddress sender,\n\t\tIERC20Upgradeable token,\n\t\tuint256 amount,\n\t\tuint64 srcChainId,\n\t\tbytes memory message,\n\t\taddress _executor\n\t) external payable onlyMessageBus returns (ExecutionStatus) {\n\t\trequire(executor == _executor, 'MessageReceiver: invalid executor');\n\t\tIDstChainPayment dstChainPayment = router.DstChainPayment();\n\t\ttoken.safeApprove(address(dstChainPayment), amount);\n\t\ttry dstChainPayment.payFromSourceChain(token, amount, message) {\n\t\t\temit MessageWithTransferExecuted(sender, token, amount, srcChainId, message, _executor);\n\t\t} catch (bytes memory err) {\n\t\t\temit MessageWithTransferFailed(sender, token, amount, srcChainId, message, _executor, err);\n\t\t}\n\t\ttoken.safeApprove(address(dstChainPayment), 0);\n\t\treturn ExecutionStatus.Success;\n\t}\n\n\t/// @dev execute message with transfer fallback\n\t/// @param _sender message sender address\n\t/// @param _token token address\n\t/// @param _amount token amount\n\t/// @param _srcChainId src chain chainId\n\t/// @param _message src chain message\n\t/// @param executor executor address\n\tfunction executeMessageWithTransferFallback(\n\t\taddress _sender,\n\t\taddress _token,\n\t\tuint256 _amount,\n\t\tuint64 _srcChainId,\n\t\tbytes memory _message,\n\t\taddress executor\n\t) external payable onlyMessageBus returns (ExecutionStatus) {\n\t\temit MessageWithTransferFallback(_sender, _token, _amount, _srcChainId, _message, executor);\n\t\treturn ExecutionStatus.Success;\n\t}\n\n\t/// @dev Explain to a developer any extra details\n\t/// @param route route info\n\t/// @param dstChainId dst chain chainId\n\t/// @param message message bytes\n\t/// @return message id\n\tfunction messageId(\n\t\tMsgDataTypes.RouteInfo calldata route,\n\t\tuint64 dstChainId,\n\t\tbytes calldata message\n\t) public view returns (bytes32) {\n\t\treturn\n\t\t\tkeccak256(abi.encodePacked(MsgDataTypes.MsgType.MessageOnly, route.sender, route.receiver, route.srcChainId, route.srcTxHash, dstChainId, message));\n\t}\n\n\t/// @dev set message bus\n\t/// @param messageBus message bus address\n\tfunction setMessageBus(address messageBus) external onlyOwner {\n\t\t_setMessageBus(messageBus);\n\t}\n\n\tfunction _setMessageBus(address _messageBus) internal {\n\t\tmessageBus = _messageBus;\n\t\temit MessageBusUpdated(messageBus);\n\t}\n\n\t/// @dev set executor address\n\t/// @param _executor executor address\n\tfunction setExecutor(address _executor) external onlyOwner {\n\t\t_setExecutor(_executor);\n\t}\n\n\tfunction _setExecutor(address _executor) internal {\n\t\texecutor = _executor;\n\t\temit ExecutorUpdated(_executor);\n\t}\n}\n"
    },
    "contracts/payments/DstChainPayment.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol';\nimport '../interfaces/IDstChainPayment.sol';\nimport '../govers/RouterWrapper.sol';\nimport '../access/OwnerWithdrawable.sol';\nimport '../access/Pauser.sol';\nimport '../libraries/ResourceData.sol';\n\n/// @author Alexandas\n/// @dev Dst chain payment contract\ncontract DstChainPayment is IDstChainPayment, ReentrancyGuardUpgradeable, OwnerWithdrawable, Pauser, RouterWrapper {\n\tusing ResourceData for ResourceData.ValuePayloads;\n\tusing SafeMathUpgradeable for uint256;\n\tusing SafeERC20Upgradeable for IERC20Upgradeable;\n\n\tmapping(address => uint256) internal balances;\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param pauser contract pauser\n\t/// @param router router contract\n\tfunction initialize(\n\t\taddress owner,\n\t\taddress pauser,\n\t\tIRouter router\n\t) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Pauser(pauser);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev pay from source chain only called by message receiver\n\t/// @param _token token address\n\t/// @param dstAmount token amount\n\t/// @param message payment payload message bytes\n\tfunction payFromSourceChain(\n\t\tIERC20Upgradeable _token,\n\t\tuint256 dstAmount,\n\t\tbytes calldata message\n\t) external override onlyMessageReceiver whenNotPaused nonReentrant {\n\t\tIERC20Upgradeable token = router.Token();\n\t\trequire(token == _token, 'DstChainPayment: invalid token');\n\t\t(address provider, uint64 nonce, bytes32 account, ResourceData.ValuePayload[] memory payloads) = decodeSourceChainMessage(message);\n\t\tuint256 value = ResourceData.matchTokenToResource(token, dstAmount);\n\t\tPaymentPayload memory payload = PaymentPayload(provider, nonce, account, ResourceData.ValuePayloads(payloads).convertSourceChainPayloads(value));\n\t\t_processPayloads(provider, payload.account, payload.payloads, false);\n\t\t_pay(payload.provider, payload.account, token, dstAmount);\n\n\t\temit Paid(token, payload);\n\t}\n\n\t/// @dev pay on dst chain\n\t/// @param payload payment payload\n\t/// @return value payment value\n\tfunction pay(PaymentPayload memory payload) external override whenNotPaused nonReentrant returns (uint256 value) {\n\t\tvalue = _processPayloads(payload.provider, payload.account, payload.payloads, true);\n\t\tIERC20Upgradeable token = router.Token();\n\t\tvalue = ResourceData.matchResourceToToken(token, value);\n\t\t_pay(payload.provider, payload.account, token, value);\n\n\t\temit Paid(token, payload);\n\t}\n\n\tfunction _pay(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tIERC20Upgradeable token,\n\t\tuint256 amount\n\t) internal {\n\t\trequire(router.ProviderController().accountExists(provider, account), 'DstChainPayment: nonexistent account');\n\t\tbalances[provider] = balances[provider].add(amount);\n\t\ttoken.safeTransferFrom(msg.sender, address(this), amount);\n\t}\n\n\tfunction _processPayloads(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tResourceData.ValuePayload[] memory payloads,\n\t\tbool withValue\n\t) internal returns (uint256 value) {\n\t\trequire(payloads.length > 0, 'DstChainPayment: invalid payloads');\n\t\tIResourcePriceAdaptor adaptor = router.ResourcePriceAdaptor();\n\t\tfor (uint256 i = 0; i < payloads.length; i++) {\n\t\t\tResourceData.ValuePayload memory payload = payloads[i];\n\t\t\tif (payload.resourceType == ResourceData.ResourceType.BuildingTime) {\n\t\t\t\trequire(payload.values.length == 1, 'DstChainPayment: invalid value length for BuildingTime');\n\t\t\t\tuint256 amount = adaptor.getAmountOf(provider, payload.resourceType, payload.values[0]);\n\t\t\t\trouter.BuildingTimeController().paymentAllocate(provider, account, amount);\n\t\t\t} else if (payload.resourceType == ResourceData.ResourceType.ARStorage) {\n\t\t\t\trequire(payload.values.length == 1, 'DstChainPayment: invalid value length for ARStorage');\n\t\t\t\tuint256 amount = adaptor.getAmountOf(provider, payload.resourceType, payload.values[0]);\n\t\t\t\trouter.ARStorageController().paymentAllocate(provider, account, amount);\n\t\t\t} else if (payload.resourceType == ResourceData.ResourceType.Bandwidth) {\n\t\t\t\trequire(payload.values.length == 1, 'DstChainPayment: invalid value length for Bandwidth');\n\t\t\t\tuint256 amount = adaptor.getAmountOf(provider, payload.resourceType, payload.values[0]);\n\t\t\t\trouter.BandwidthController().paymentAllocate(provider, account, amount);\n\t\t\t} else if (payload.resourceType == ResourceData.ResourceType.IPFSStorage) {\n\t\t\t\trequire(payload.values.length == 2, 'DstChainPayment: invalid value length for IPFSStorage');\n\t\t\t\t(uint256 amount, uint256 expiration) = ipfsAllocations(provider, account, payload.values[0], payload.values[1]);\n\t\t\t\trouter.IPFSStorageController().paymentAllocate(provider, account, amount, expiration);\n\t\t\t} else {\n\t\t\t\trevert('DstChainPayment: unknown resource type');\n\t\t\t}\n\t\t\tif (withValue) {\n\t\t\t\tfor (uint256 j = 0; j < payload.values.length; j++) {\n\t\t\t\t\tvalue = value.add(payload.values[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/// @dev decode source chain message\n\t/// @param message message bytes\n\t/// @return provider provider address\n\t/// @return nonce nonce\n\t/// @return account user account\n\t/// @return payloads payment payloads\n\tfunction decodeSourceChainMessage(bytes memory message)\n\t\tpublic\n\t\tview\n\t\treturns (\n\t\t\taddress provider,\n\t\t\tuint64 nonce,\n\t\t\tbytes32 account,\n\t\t\tResourceData.ValuePayload[] memory payloads\n\t\t)\n\t{\n\t\t(provider, nonce, account, payloads) = abi.decode(message, (address, uint64, bytes32, ResourceData.ValuePayload[]));\n\t}\n\n\t/// @dev calculate fee for ipfs storage and expiration\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param amount ipfs storage amount\n\t/// @param expiration ipfs expiration(in seconds)\n\t/// @return storageFee ipfs storage fee\n\t/// @return expirationFee ipfs expiration fee\n\tfunction ipfsAlloctionsFee(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 amount,\n\t\tuint256 expiration\n\t) public view override returns (uint256 storageFee, uint256 expirationFee) {\n\t\tIIPFSStorageController controller = router.IPFSStorageController();\n\t\taddress p = provider;\n\t\tbytes32 a = account;\n\t\tif (controller.isExpired(p, a)) {\n\t\t\trequire(amount > 0 && expiration > 0, 'DstChainPayment: invalid params for expired account');\n\t\t\tstorageFee = getValueOf(p, ResourceData.ResourceType.IPFSStorage, amount);\n\t\t\texpirationFee = storageFee.mul(expiration);\n\t\t} else {\n\t\t\trequire(amount > 0 || expiration > 0, 'DstChainPayment: invalid params');\n\t\t\tstorageFee = amount.mul(getValueOf(p, ResourceData.ResourceType.IPFSStorage, controller.availableExpiration(p, a)));\n\t\t\texpirationFee = expiration.mul(getValueOf(p, ResourceData.ResourceType.IPFSStorage, controller.balanceOf(p, a).add(amount)));\n\t\t}\n\t}\n\n\t/// @dev calculate ipfs storage and expiration with storage fee and expiration fee\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param storageFee storage fee\n\t/// @param expirationFee expiration fee\n\t/// @return amount ipfs storage amount\n\t/// @return expiration ipfs expiration(in seconds)\n\tfunction ipfsAllocations(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tuint256 storageFee,\n\t\tuint256 expirationFee\n\t) public view override returns (uint256 amount, uint256 expiration) {\n\t\tIIPFSStorageController controller = router.IPFSStorageController();\n\t\taddress p = provider;\n\t\tbytes32 a = account;\n\t\tif (controller.isExpired(p, a)) {\n\t\t\trequire(storageFee > 0 && expirationFee > 0, 'DstChainPayment: invalid params for expired account');\n\t\t\tamount = storageFee.div(priceOf(p, ResourceData.ResourceType.IPFSStorage));\n\t\t\texpiration = expirationFee.div(storageFee);\n\t\t} else {\n\t\t\trequire(storageFee > 0 || expirationFee > 0, 'DstChainPayment: invalid params');\n\t\t\tamount = storageFee.div(getValueOf(p, ResourceData.ResourceType.IPFSStorage, controller.availableExpiration(p, a)));\n\t\t\texpiration = expirationFee.div(getValueOf(p, ResourceData.ResourceType.IPFSStorage, controller.balanceOf(p, a).add(amount)));\n\t\t}\n\t}\n\n\t/// @dev return balance of provider\n\t/// @param provider provider address\n\t/// @return balance of provider\n\tfunction balanceOf(address provider) public view override returns (uint256) {\n\t\trequire(router.ProviderRegistry().isProvider(provider), 'DstChainPayment: nonexistent provider');\n\t\treturn balances[provider];\n\t}\n\n\t/// @dev return resource price\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @return resource price\n\tfunction priceOf(address provider, ResourceData.ResourceType resourceType) public view override returns (uint256) {\n\t\tIResourcePriceAdaptor adaptor = router.ResourcePriceAdaptor();\n\t\treturn adaptor.priceOf(provider, resourceType);\n\t}\n\n\t/// @dev return value of amount resource\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param amount resource amount\n\t/// @return token value\n\tfunction getValueOf(\n\t\taddress provider,\n\t\tResourceData.ResourceType resourceType,\n\t\tuint256 amount\n\t) public view override returns (uint256) {\n\t\tIResourcePriceAdaptor adaptor = router.ResourcePriceAdaptor();\n\t\treturn adaptor.getValueOf(provider, resourceType, amount);\n\t}\n\n\t/// @dev return resource amount with value\n\t/// @param provider provider address\n\t/// @param resourceType resource type\n\t/// @param value token value\n\t/// @return resource amount\n\tfunction getAmountOf(\n\t\taddress provider,\n\t\tResourceData.ResourceType resourceType,\n\t\tuint256 value\n\t) public view override returns (uint256) {\n\t\tIResourcePriceAdaptor adaptor = router.ResourcePriceAdaptor();\n\t\treturn adaptor.getAmountOf(provider, resourceType, value);\n\t}\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/utils/cryptography/SignatureCheckerUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../AddressUpgradeable.sol\";\nimport \"../../interfaces/IERC1271Upgradeable.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureCheckerUpgradeable {\n    /**\n     * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n     * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n     *\n     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n     * change through time. It could return true at block N and false at block N+1 (or the opposite).\n     */\n    function isValidSignatureNow(\n        address signer,\n        bytes32 hash,\n        bytes memory signature\n    ) internal view returns (bool) {\n        (address recovered, ECDSAUpgradeable.RecoverError error) = ECDSAUpgradeable.tryRecover(hash, signature);\n        if (error == ECDSAUpgradeable.RecoverError.NoError && recovered == signer) {\n            return true;\n        }\n\n        (bool success, bytes memory result) = signer.staticcall(\n            abi.encodeWithSelector(IERC1271Upgradeable.isValidSignature.selector, hash, signature)\n        );\n        return (success && result.length == 32 && abi.decode(result, (bytes4)) == IERC1271Upgradeable.isValidSignature.selector);\n    }\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/interfaces/IERC1271Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271Upgradeable {\n    /**\n     * @dev Should return whether the signature provided is valid for the provided data\n     * @param hash      Hash of the data to be signed\n     * @param signature Signature byte array associated with _data\n     */\n    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"
    },
    "contracts/messages/MessageSender.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol';\nimport 'sgn-v2-contracts/contracts/message/interfaces/IMessageBus.sol';\nimport 'sgn-v2-contracts/contracts/message/libraries/MessageSenderLib.sol';\n\nimport '../interfaces/IMessageSender.sol';\nimport '../access/OwnerWithdrawable.sol';\n\n/// @author Alexandas\n/// @dev Celer SGN source chain sender contract\ncontract MessageSender is IMessageSender, OwnerWithdrawable {\n\tusing SafeERC20Upgradeable for IERC20Upgradeable;\n\n\tenum ExecutionStatus {\n\t\tFail,\n\t\tSuccess,\n\t\tRetry\n\t}\n\n\t/// @dev src chain payment address\n\taddress public srcChainPayment;\n\n\t/// @dev src chain messageBus address\n\taddress public messageBus;\n\n\t/// @dev dst chain receiver address\n\taddress public override receiver;\n\n\t/// @dev dst chainId\n\tuint64 public override dstChainId;\n\n\tmodifier onlyMessageBus() {\n\t\trequire(msg.sender == messageBus, 'MessageReceiver: caller is not message bus');\n\t\t_;\n\t}\n\n\tmodifier onlySrcChainPayment() {\n\t\trequire(msg.sender == srcChainPayment, 'MessageSender: caller is not payment contract');\n\t\t_;\n\t}\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param _messageBus src chain messageBus\n\t/// @param _receiver dst chain receiver\n\t/// @param _dstChainId dst chain chainId\n\tfunction initialize(\n\t\taddress owner,\n\t\taddress _messageBus,\n\t\taddress _receiver,\n\t\tuint64 _dstChainId\n\t) external initializer {\n\t\t_transferOwnership(owner);\n\t\t_setMessageBus(_messageBus);\n\t\t_setReceiver(_receiver);\n\t\t_setDstChainId(_dstChainId);\n\t}\n\n\t/// @dev sendMessageWithTransfer to dst chain\n\t/// @param token src payment token address\n\t/// @param amount token amount\n\t/// @param nonce nonce\n\t/// @param maxSlippage maxSlippage for sgn cBridge\n\t/// @param message message to dst chain\n\t/// @param bridgeSendType bridge send type for sgn cBridge\n\tfunction sendMessageWithTransfer(\n\t\taddress token,\n\t\tuint256 amount,\n\t\tuint64 nonce,\n\t\tuint32 maxSlippage,\n\t\tbytes memory message,\n\t\tMsgDataTypes.BridgeSendType bridgeSendType\n\t) external payable onlySrcChainPayment returns (bytes32) {\n\t\tIERC20Upgradeable(token).transferFrom(msg.sender, address(this), amount);\n\t\tMessageSenderLib.sendMessageWithTransfer(receiver, token, amount, dstChainId, nonce, maxSlippage, message, bridgeSendType, messageBus, msg.value);\n\t}\n\n\t/// @dev call when cBridge transfer failed\n\t/// @param _token token address\n\t/// @param _amount token amount\n\t/// @param _message message\n\t/// @param executor exector address\n\tfunction executeMessageWithTransferRefund(\n\t\taddress _token,\n\t\tuint256 _amount,\n\t\tbytes calldata _message,\n\t\taddress executor\n\t) external payable onlyMessageBus returns (ExecutionStatus) {\n\t\temit MessageWithTransferRefund(_token, _amount, _message, executor);\n\t\treturn ExecutionStatus.Success;\n\t}\n\n\t/// @dev set src chain payment\n\t/// @param _payment src chain payment address\n\tfunction setSrcChainPayment(address _payment) external onlyOwner {\n\t\t_setSrcChainPayment(_payment);\n\t}\n\n\tfunction _setSrcChainPayment(address _payment) internal {\n\t\tsrcChainPayment = _payment;\n\t\temit SrcChainPaymentUpdated(_payment);\n\t}\n\n\t/// @dev update message bus\n\t/// @param messageBus message bus address\n\tfunction setMessageBus(address messageBus) external onlyOwner {\n\t\t_setMessageBus(messageBus);\n\t}\n\n\tfunction _setMessageBus(address _messageBus) internal {\n\t\tmessageBus = _messageBus;\n\t\temit MessageBusUpdated(messageBus);\n\t}\n\n\t/// @dev set dst chain chainId\n\t/// @param dstChainId dst chainId\n\tfunction setDstChainId(uint64 dstChainId) external onlyOwner {\n\t\t_setDstChainId(dstChainId);\n\t}\n\n\tfunction _setDstChainId(uint64 _dstChainId) internal {\n\t\tdstChainId = _dstChainId;\n\t\temit DstChainIdUpdated(_dstChainId);\n\t}\n\n\t/// @dev set dst chain receiver\n\t/// @param _receiver dst chain receiver\n\tfunction setReceiver(address _receiver) external onlyOwner {\n\t\t_setReceiver(_receiver);\n\t}\n\n\tfunction _setReceiver(address _receiver) internal {\n\t\treceiver = _receiver;\n\t\temit ReceiverUpdated(_receiver);\n\t}\n\n\t/// @dev calculate message fee\n\t/// @param message message bytes\n\t/// @return fee\n\tfunction calcFee(bytes memory message) public view override returns (uint256) {\n\t\treturn IMessageBus(messageBus).calcFee(message);\n\t}\n\n\t/// @dev messageId for message bus\n\t/// @param route message route info\n\t/// @param dstChainId message route info\n\t/// @param message message bytes\n\tfunction messageId(\n\t\tMsgDataTypes.RouteInfo calldata route,\n\t\tuint64 dstChainId,\n\t\tbytes calldata message\n\t) external view override returns (bytes32) {\n\t\treturn\n\t\t\tkeccak256(abi.encodePacked(MsgDataTypes.MsgType.MessageOnly, route.sender, route.receiver, route.srcChainId, route.srcTxHash, dstChainId, message));\n\t}\n}\n"
    },
    "sgn-v2-contracts/contracts/message/interfaces/IMessageBus.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport \"../libraries/MsgDataTypes.sol\";\n\ninterface IMessageBus {\n    function liquidityBridge() external view returns (address);\n\n    function pegBridge() external view returns (address);\n\n    function pegBridgeV2() external view returns (address);\n\n    function pegVault() external view returns (address);\n\n    function pegVaultV2() external view returns (address);\n\n    /**\n     * @notice Calculates the required fee for the message.\n     * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n     @ @return The required fee.\n     */\n    function calcFee(bytes calldata _message) external view returns (uint256);\n\n    /**\n     * @notice Sends a message to an app on another chain via MessageBus without an associated transfer.\n     * A fee is charged in the native gas token.\n     * @param _receiver The address of the destination app contract.\n     * @param _dstChainId The destination chain ID.\n     * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n     */\n    function sendMessage(\n        address _receiver,\n        uint256 _dstChainId,\n        bytes calldata _message\n    ) external payable;\n\n    /**\n     * @notice Sends a message associated with a transfer to an app on another chain via MessageBus without an associated transfer.\n     * A fee is charged in the native token.\n     * @param _receiver The address of the destination app contract.\n     * @param _dstChainId The destination chain ID.\n     * @param _srcBridge The bridge contract to send the transfer with.\n     * @param _srcTransferId The transfer ID.\n     * @param _dstChainId The destination chain ID.\n     * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n     */\n    function sendMessageWithTransfer(\n        address _receiver,\n        uint256 _dstChainId,\n        address _srcBridge,\n        bytes32 _srcTransferId,\n        bytes calldata _message\n    ) external payable;\n\n    /**\n     * @notice Withdraws message fee in the form of native gas token.\n     * @param _account The address receiving the fee.\n     * @param _cumulativeFee The cumulative fee credited to the account. Tracked by SGN.\n     * @param _sigs The list of signatures sorted by signing addresses in ascending order. A withdrawal must be\n     * signed-off by +2/3 of the sigsVerifier's current signing power to be delivered.\n     * @param _signers The sorted list of signers.\n     * @param _powers The signing powers of the signers.\n     */\n    function withdrawFee(\n        address _account,\n        uint256 _cumulativeFee,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external;\n\n    /**\n     * @notice Execute a message with a successful transfer.\n     * @param _message Arbitrary message bytes originated from and encoded by the source app contract\n     * @param _transfer The transfer info.\n     * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n     * +2/3 of the sigsVerifier's current signing power to be delivered.\n     * @param _signers The sorted list of signers.\n     * @param _powers The signing powers of the signers.\n     */\n    function executeMessageWithTransfer(\n        bytes calldata _message,\n        MsgDataTypes.TransferInfo calldata _transfer,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external payable;\n\n    /**\n     * @notice Execute a message with a refunded transfer.\n     * @param _message Arbitrary message bytes originated from and encoded by the source app contract\n     * @param _transfer The transfer info.\n     * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n     * +2/3 of the sigsVerifier's current signing power to be delivered.\n     * @param _signers The sorted list of signers.\n     * @param _powers The signing powers of the signers.\n     */\n    function executeMessageWithTransferRefund(\n        bytes calldata _message, // the same message associated with the original transfer\n        MsgDataTypes.TransferInfo calldata _transfer,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external payable;\n\n    /**\n     * @notice Execute a message not associated with a transfer.\n     * @param _message Arbitrary message bytes originated from and encoded by the source app contract\n     * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n     * +2/3 of the sigsVerifier's current signing power to be delivered.\n     * @param _signers The sorted list of signers.\n     * @param _powers The signing powers of the signers.\n     */\n    function executeMessage(\n        bytes calldata _message,\n        MsgDataTypes.RouteInfo calldata _route,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external payable;\n}\n"
    },
    "sgn-v2-contracts/contracts/message/libraries/MessageSenderLib.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"../../interfaces/IBridge.sol\";\nimport \"../../interfaces/IOriginalTokenVault.sol\";\nimport \"../../interfaces/IOriginalTokenVaultV2.sol\";\nimport \"../../interfaces/IPeggedTokenBridge.sol\";\nimport \"../../interfaces/IPeggedTokenBridgeV2.sol\";\nimport \"../interfaces/IMessageBus.sol\";\nimport \"./MsgDataTypes.sol\";\n\nlibrary MessageSenderLib {\n    using SafeERC20 for IERC20;\n\n    // ============== Internal library functions called by apps ==============\n\n    /**\n     * @notice Sends a message to an app on another chain via MessageBus without an associated transfer.\n     * @param _receiver The address of the destination app contract.\n     * @param _dstChainId The destination chain ID.\n     * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n     * @param _messageBus The address of the MessageBus on this chain.\n     * @param _fee The fee amount to pay to MessageBus.\n     */\n    function sendMessage(\n        address _receiver,\n        uint64 _dstChainId,\n        bytes memory _message,\n        address _messageBus,\n        uint256 _fee\n    ) internal {\n        IMessageBus(_messageBus).sendMessage{value: _fee}(_receiver, _dstChainId, _message);\n    }\n\n    /**\n     * @notice Sends a message to an app on another chain via MessageBus with an associated transfer.\n     * @param _receiver The address of the destination app contract.\n     * @param _token The address of the token to be sent.\n     * @param _amount The amount of tokens to be sent.\n     * @param _dstChainId The destination chain ID.\n     * @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.\n     * @param _maxSlippage The max slippage accepted, given as percentage in point (pip). Eg. 5000 means 0.5%.\n     * Must be greater than minimalMaxSlippage. Receiver is guaranteed to receive at least (100% - max slippage percentage) * amount or the\n     * transfer can be refunded. Only applicable to the {MsgDataTypes.BridgeSendType.Liquidity}.\n     * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n     * @param _bridgeSendType One of the {MsgDataTypes.BridgeSendType} enum.\n     * @param _messageBus The address of the MessageBus on this chain.\n     * @param _fee The fee amount to pay to MessageBus.\n     * @return The transfer ID.\n     */\n    function sendMessageWithTransfer(\n        address _receiver,\n        address _token,\n        uint256 _amount,\n        uint64 _dstChainId,\n        uint64 _nonce,\n        uint32 _maxSlippage,\n        bytes memory _message,\n        MsgDataTypes.BridgeSendType _bridgeSendType,\n        address _messageBus,\n        uint256 _fee\n    ) internal returns (bytes32) {\n        if (_bridgeSendType == MsgDataTypes.BridgeSendType.Liquidity) {\n            return\n                sendMessageWithLiquidityBridgeTransfer(\n                    _receiver,\n                    _token,\n                    _amount,\n                    _dstChainId,\n                    _nonce,\n                    _maxSlippage,\n                    _message,\n                    _messageBus,\n                    _fee\n                );\n        } else if (\n            _bridgeSendType == MsgDataTypes.BridgeSendType.PegDeposit ||\n            _bridgeSendType == MsgDataTypes.BridgeSendType.PegV2Deposit\n        ) {\n            return\n                sendMessageWithPegVaultDeposit(\n                    _bridgeSendType,\n                    _receiver,\n                    _token,\n                    _amount,\n                    _dstChainId,\n                    _nonce,\n                    _message,\n                    _messageBus,\n                    _fee\n                );\n        } else if (\n            _bridgeSendType == MsgDataTypes.BridgeSendType.PegBurn ||\n            _bridgeSendType == MsgDataTypes.BridgeSendType.PegV2Burn\n        ) {\n            return\n                sendMessageWithPegBridgeBurn(\n                    _bridgeSendType,\n                    _receiver,\n                    _token,\n                    _amount,\n                    _dstChainId,\n                    _nonce,\n                    _message,\n                    _messageBus,\n                    _fee\n                );\n        } else {\n            revert(\"bridge type not supported\");\n        }\n    }\n\n    /**\n     * @notice Sends a message to an app on another chain via MessageBus with an associated liquidity bridge transfer.\n     * @param _receiver The address of the destination app contract.\n     * @param _token The address of the token to be sent.\n     * @param _amount The amount of tokens to be sent.\n     * @param _dstChainId The destination chain ID.\n     * @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.\n     * @param _maxSlippage The max slippage accepted, given as percentage in point (pip). Eg. 5000 means 0.5%.\n     * Must be greater than minimalMaxSlippage. Receiver is guaranteed to receive at least (100% - max slippage percentage) * amount or the\n     * transfer can be refunded.\n     * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n     * @param _messageBus The address of the MessageBus on this chain.\n     * @param _fee The fee amount to pay to MessageBus.\n     * @return The transfer ID.\n     */\n    function sendMessageWithLiquidityBridgeTransfer(\n        address _receiver,\n        address _token,\n        uint256 _amount,\n        uint64 _dstChainId,\n        uint64 _nonce,\n        uint32 _maxSlippage,\n        bytes memory _message,\n        address _messageBus,\n        uint256 _fee\n    ) internal returns (bytes32) {\n        address bridge = IMessageBus(_messageBus).liquidityBridge();\n        IERC20(_token).safeIncreaseAllowance(bridge, _amount);\n        IBridge(bridge).send(_receiver, _token, _amount, _dstChainId, _nonce, _maxSlippage);\n        bytes32 transferId = keccak256(\n            abi.encodePacked(address(this), _receiver, _token, _amount, _dstChainId, _nonce, uint64(block.chainid))\n        );\n        IMessageBus(_messageBus).sendMessageWithTransfer{value: _fee}(\n            _receiver,\n            _dstChainId,\n            bridge,\n            transferId,\n            _message\n        );\n        return transferId;\n    }\n\n    /**\n     * @notice Sends a message to an app on another chain via MessageBus with an associated OriginalTokenVault deposit.\n     * @param _receiver The address of the destination app contract.\n     * @param _token The address of the token to be sent.\n     * @param _amount The amount of tokens to be sent.\n     * @param _dstChainId The destination chain ID.\n     * @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.\n     * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n     * @param _messageBus The address of the MessageBus on this chain.\n     * @param _fee The fee amount to pay to MessageBus.\n     * @return The transfer ID.\n     */\n    function sendMessageWithPegVaultDeposit(\n        MsgDataTypes.BridgeSendType _bridgeSendType,\n        address _receiver,\n        address _token,\n        uint256 _amount,\n        uint64 _dstChainId,\n        uint64 _nonce,\n        bytes memory _message,\n        address _messageBus,\n        uint256 _fee\n    ) internal returns (bytes32) {\n        address pegVault;\n        if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegDeposit) {\n            pegVault = IMessageBus(_messageBus).pegVault();\n        } else {\n            pegVault = IMessageBus(_messageBus).pegVaultV2();\n        }\n        IERC20(_token).safeIncreaseAllowance(pegVault, _amount);\n        bytes32 transferId;\n        if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegDeposit) {\n            IOriginalTokenVault(pegVault).deposit(_token, _amount, _dstChainId, _receiver, _nonce);\n            transferId = keccak256(\n                abi.encodePacked(address(this), _token, _amount, _dstChainId, _receiver, _nonce, uint64(block.chainid))\n            );\n        } else {\n            transferId = IOriginalTokenVaultV2(pegVault).deposit(_token, _amount, _dstChainId, _receiver, _nonce);\n        }\n        IMessageBus(_messageBus).sendMessageWithTransfer{value: _fee}(\n            _receiver,\n            _dstChainId,\n            pegVault,\n            transferId,\n            _message\n        );\n        return transferId;\n    }\n\n    /**\n     * @notice Sends a message to an app on another chain via MessageBus with an associated PeggedTokenBridge burn.\n     * @param _receiver The address of the destination app contract.\n     * @param _token The address of the token to be sent.\n     * @param _amount The amount of tokens to be sent.\n     * @param _dstChainId The destination chain ID.\n     * @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.\n     * @param _message Arbitrary message bytes to be decoded by the destination app contract.\n     * @param _messageBus The address of the MessageBus on this chain.\n     * @param _fee The fee amount to pay to MessageBus.\n     * @return The transfer ID.\n     */\n    function sendMessageWithPegBridgeBurn(\n        MsgDataTypes.BridgeSendType _bridgeSendType,\n        address _receiver,\n        address _token,\n        uint256 _amount,\n        uint64 _dstChainId,\n        uint64 _nonce,\n        bytes memory _message,\n        address _messageBus,\n        uint256 _fee\n    ) internal returns (bytes32) {\n        address pegBridge;\n        if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegBurn) {\n            pegBridge = IMessageBus(_messageBus).pegBridge();\n        } else {\n            pegBridge = IMessageBus(_messageBus).pegBridgeV2();\n        }\n        IERC20(_token).safeIncreaseAllowance(pegBridge, _amount);\n        bytes32 transferId;\n        if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegBurn) {\n            IPeggedTokenBridge(pegBridge).burn(_token, _amount, _receiver, _nonce);\n            transferId = keccak256(\n                abi.encodePacked(address(this), _token, _amount, _receiver, _nonce, uint64(block.chainid))\n            );\n        } else {\n            transferId = IPeggedTokenBridgeV2(pegBridge).burn(_token, _amount, _dstChainId, _receiver, _nonce);\n        }\n        // handle cases where certain tokens do not spend allowance for role-based burn\n        IERC20(_token).safeApprove(pegBridge, 0);\n        IMessageBus(_messageBus).sendMessageWithTransfer{value: _fee}(\n            _receiver,\n            _dstChainId,\n            pegBridge,\n            transferId,\n            _message\n        );\n        return transferId;\n    }\n\n    /**\n     * @notice Sends a token transfer via a bridge.\n     * @param _receiver The address of the destination app contract.\n     * @param _token The address of the token to be sent.\n     * @param _amount The amount of tokens to be sent.\n     * @param _dstChainId The destination chain ID.\n     * @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.\n     * @param _maxSlippage The max slippage accepted, given as percentage in point (pip). Eg. 5000 means 0.5%.\n     * Must be greater than minimalMaxSlippage. Receiver is guaranteed to receive at least (100% - max slippage percentage) * amount or the\n     * transfer can be refunded.\n     * @param _bridgeSendType One of the {MsgDataTypes.BridgeSendType} enum.\n     */\n    function sendTokenTransfer(\n        address _receiver,\n        address _token,\n        uint256 _amount,\n        uint64 _dstChainId,\n        uint64 _nonce,\n        uint32 _maxSlippage,\n        MsgDataTypes.BridgeSendType _bridgeSendType,\n        address _bridge\n    ) internal {\n        IERC20(_token).safeIncreaseAllowance(_bridge, _amount);\n        if (_bridgeSendType == MsgDataTypes.BridgeSendType.Liquidity) {\n            IBridge(_bridge).send(_receiver, _token, _amount, _dstChainId, _nonce, _maxSlippage);\n        } else if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegDeposit) {\n            IOriginalTokenVault(_bridge).deposit(_token, _amount, _dstChainId, _receiver, _nonce);\n        } else if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegBurn) {\n            IPeggedTokenBridge(_bridge).burn(_token, _amount, _receiver, _nonce);\n            // handle cases where certain tokens do not spend allowance for role-based burn\n            IERC20(_token).safeApprove(_bridge, 0);\n        } else if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegV2Deposit) {\n            IOriginalTokenVaultV2(_bridge).deposit(_token, _amount, _dstChainId, _receiver, _nonce);\n        } else if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegV2Burn) {\n            IPeggedTokenBridgeV2(_bridge).burn(_token, _amount, _dstChainId, _receiver, _nonce);\n            // handle cases where certain tokens do not spend allowance for role-based burn\n            IERC20(_token).safeApprove(_bridge, 0);\n        } else if (_bridgeSendType == MsgDataTypes.BridgeSendType.PegV2BurnFrom) {\n            IPeggedTokenBridgeV2(_bridge).burnFrom(_token, _amount, _dstChainId, _receiver, _nonce);\n            // handle cases where certain tokens do not spend allowance for role-based burn\n            IERC20(_token).safeApprove(_bridge, 0);\n        } else {\n            revert(\"bridge type not supported\");\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"
    },
    "sgn-v2-contracts/contracts/interfaces/IBridge.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IBridge {\n    function send(\n        address _receiver,\n        address _token,\n        uint256 _amount,\n        uint64 _dstChainId,\n        uint64 _nonce,\n        uint32 _maxSlippage\n    ) external;\n\n    function relay(\n        bytes calldata _relayRequest,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external;\n\n    function transfers(bytes32 transferId) external view returns (bool);\n\n    function withdraws(bytes32 withdrawId) external view returns (bool);\n\n    function withdraw(\n        bytes calldata _wdmsg,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external;\n\n    /**\n     * @notice Verifies that a message is signed by a quorum among the signers.\n     * @param _msg signed message\n     * @param _sigs list of signatures sorted by signer addresses in ascending order\n     * @param _signers sorted list of current signers\n     * @param _powers powers of current signers\n     */\n    function verifySigs(\n        bytes memory _msg,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external view;\n}\n"
    },
    "sgn-v2-contracts/contracts/interfaces/IOriginalTokenVault.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IOriginalTokenVault {\n    /**\n     * @notice Lock original tokens to trigger mint at a remote chain's PeggedTokenBridge\n     * @param _token local token address\n     * @param _amount locked token amount\n     * @param _mintChainId destination chainId to mint tokens\n     * @param _mintAccount destination account to receive minted tokens\n     * @param _nonce user input to guarantee unique depositId\n     */\n    function deposit(\n        address _token,\n        uint256 _amount,\n        uint64 _mintChainId,\n        address _mintAccount,\n        uint64 _nonce\n    ) external;\n\n    /**\n     * @notice Withdraw locked original tokens triggered by a burn at a remote chain's PeggedTokenBridge.\n     * @param _request The serialized Withdraw protobuf.\n     * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n     * +2/3 of the bridge's current signing power to be delivered.\n     * @param _signers The sorted list of signers.\n     * @param _powers The signing powers of the signers.\n     */\n    function withdraw(\n        bytes calldata _request,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external;\n\n    function records(bytes32 recordId) external view returns (bool);\n}\n"
    },
    "sgn-v2-contracts/contracts/interfaces/IOriginalTokenVaultV2.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IOriginalTokenVaultV2 {\n    /**\n     * @notice Lock original tokens to trigger mint at a remote chain's PeggedTokenBridge\n     * @param _token local token address\n     * @param _amount locked token amount\n     * @param _mintChainId destination chainId to mint tokens\n     * @param _mintAccount destination account to receive minted tokens\n     * @param _nonce user input to guarantee unique depositId\n     */\n    function deposit(\n        address _token,\n        uint256 _amount,\n        uint64 _mintChainId,\n        address _mintAccount,\n        uint64 _nonce\n    ) external returns (bytes32);\n\n    /**\n     * @notice Withdraw locked original tokens triggered by a burn at a remote chain's PeggedTokenBridge.\n     * @param _request The serialized Withdraw protobuf.\n     * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n     * +2/3 of the bridge's current signing power to be delivered.\n     * @param _signers The sorted list of signers.\n     * @param _powers The signing powers of the signers.\n     */\n    function withdraw(\n        bytes calldata _request,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external returns (bytes32);\n\n    function records(bytes32 recordId) external view returns (bool);\n}\n"
    },
    "sgn-v2-contracts/contracts/interfaces/IPeggedTokenBridge.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IPeggedTokenBridge {\n    /**\n     * @notice Burn tokens to trigger withdrawal at a remote chain's OriginalTokenVault\n     * @param _token local token address\n     * @param _amount locked token amount\n     * @param _withdrawAccount account who withdraw original tokens on the remote chain\n     * @param _nonce user input to guarantee unique depositId\n     */\n    function burn(\n        address _token,\n        uint256 _amount,\n        address _withdrawAccount,\n        uint64 _nonce\n    ) external;\n\n    /**\n     * @notice Mint tokens triggered by deposit at a remote chain's OriginalTokenVault.\n     * @param _request The serialized Mint protobuf.\n     * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n     * +2/3 of the sigsVerifier's current signing power to be delivered.\n     * @param _signers The sorted list of signers.\n     * @param _powers The signing powers of the signers.\n     */\n    function mint(\n        bytes calldata _request,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external;\n\n    function records(bytes32 recordId) external view returns (bool);\n}\n"
    },
    "sgn-v2-contracts/contracts/interfaces/IPeggedTokenBridgeV2.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\ninterface IPeggedTokenBridgeV2 {\n    /**\n     * @notice Burn pegged tokens to trigger a cross-chain withdrawal of the original tokens at a remote chain's\n     * OriginalTokenVault, or mint at another remote chain\n     * @param _token The pegged token address.\n     * @param _amount The amount to burn.\n     * @param _toChainId If zero, withdraw from original vault; otherwise, the remote chain to mint tokens.\n     * @param _toAccount The account to receive tokens on the remote chain\n     * @param _nonce A number to guarantee unique depositId. Can be timestamp in practice.\n     */\n    function burn(\n        address _token,\n        uint256 _amount,\n        uint64 _toChainId,\n        address _toAccount,\n        uint64 _nonce\n    ) external returns (bytes32);\n\n    // same with `burn` above, use openzeppelin ERC20Burnable interface\n    function burnFrom(\n        address _token,\n        uint256 _amount,\n        uint64 _toChainId,\n        address _toAccount,\n        uint64 _nonce\n    ) external returns (bytes32);\n\n    /**\n     * @notice Mint tokens triggered by deposit at a remote chain's OriginalTokenVault.\n     * @param _request The serialized Mint protobuf.\n     * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by\n     * +2/3 of the sigsVerifier's current signing power to be delivered.\n     * @param _signers The sorted list of signers.\n     * @param _powers The signing powers of the signers.\n     */\n    function mint(\n        bytes calldata _request,\n        bytes[] calldata _sigs,\n        address[] calldata _signers,\n        uint256[] calldata _powers\n    ) external returns (bytes32);\n\n    function records(bytes32 recordId) external view returns (bool);\n}\n"
    },
    "@openzeppelin/contracts/utils/Address.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n    // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Perform implementation upgrade\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Perform implementation upgrade with additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCall(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _upgradeTo(newImplementation);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(newImplementation, data);\n        }\n    }\n\n    /**\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        // Upgrades from old implementations will perform a rollback test. This test requires the new\n        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n        // this special case will break upgrade paths from old UUPS implementation to new ones.\n        if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n            _setImplementation(newImplementation);\n        } else {\n            try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n                require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n            } catch {\n                revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n            }\n            _upgradeToAndCall(newImplementation, data, forceCall);\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _changeAdmin(address newAdmin) internal {\n        emit AdminChanged(_getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n     */\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Emitted when the beacon is upgraded.\n     */\n    event BeaconUpgraded(address indexed beacon);\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function _getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n        require(\n            Address.isContract(IBeacon(newBeacon).implementation()),\n            \"ERC1967: beacon implementation is not a contract\"\n        );\n        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n    }\n\n    /**\n     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n     *\n     * Emits a {BeaconUpgraded} event.\n     */\n    function _upgradeBeaconToAndCall(\n        address newBeacon,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {BeaconProxy} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"
    },
    "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"
    },
    "@openzeppelin/contracts/utils/StorageSlot.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n}\n"
    },
    "contracts/proxy/AdminWrapper.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts/utils/StorageSlot.sol';\n\n/// @author Alexandas\n/// @dev proxy admin wrapper\ncontract AdminWrapper {\n\t/// @dev return admin address from storage slot\n\t/// @return admin admin contract address\n\tfunction _getAdmin() internal view returns (address) {\n\t\t// bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1))\n\t\tbytes32 _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\t\treturn StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n\t}\n\n\tmodifier onlyAdmin() {\n\t\trequire(msg.sender == _getAdmin(), 'AdminWrapper: caller is not the admin');\n\t\t_;\n\t}\n}\n"
    },
    "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n    /**\n     * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n     *\n     * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n     * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n     */\n    constructor(address _logic, bytes memory _data) payable {\n        assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n        _upgradeToAndCall(_logic, _data, false);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _implementation() internal view virtual override returns (address impl) {\n        return ERC1967Upgrade._getImplementation();\n    }\n}\n"
    },
    "@openzeppelin/contracts/proxy/Proxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n    /**\n     * @dev Delegates the current call to `implementation`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _delegate(address implementation) internal virtual {\n        assembly {\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n\n    /**\n     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n     * and {_fallback} should delegate.\n     */\n    function _implementation() internal view virtual returns (address);\n\n    /**\n     * @dev Delegates the current call to the address returned by `_implementation()`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _fallback() internal virtual {\n        _beforeFallback();\n        _delegate(_implementation());\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n     * function in the contract matches the call data.\n     */\n    fallback() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n     * is empty.\n     */\n    receive() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n     * call, or as part of the Solidity `fallback` or `receive` functions.\n     *\n     * If overridden should call `super._beforeFallback()`.\n     */\n    function _beforeFallback() internal virtual {}\n}\n"
    },
    "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n    /**\n     * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n     * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n     */\n    constructor(\n        address _logic,\n        address admin_,\n        bytes memory _data\n    ) payable ERC1967Proxy(_logic, _data) {\n        assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n        _changeAdmin(admin_);\n    }\n\n    /**\n     * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n     */\n    modifier ifAdmin() {\n        if (msg.sender == _getAdmin()) {\n            _;\n        } else {\n            _fallback();\n        }\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function admin() external ifAdmin returns (address admin_) {\n        admin_ = _getAdmin();\n    }\n\n    /**\n     * @dev Returns the current implementation.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n     */\n    function implementation() external ifAdmin returns (address implementation_) {\n        implementation_ = _implementation();\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n     */\n    function changeAdmin(address newAdmin) external virtual ifAdmin {\n        _changeAdmin(newAdmin);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n     */\n    function upgradeTo(address newImplementation) external ifAdmin {\n        _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n     * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n     * proxied contract.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n     */\n    function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n        _upgradeToAndCall(newImplementation, data, true);\n    }\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _admin() internal view virtual returns (address) {\n        return _getAdmin();\n    }\n\n    /**\n     * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n     */\n    function _beforeFallback() internal virtual override {\n        require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n        super._beforeFallback();\n    }\n}\n"
    },
    "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n    /**\n     * @dev Returns the current implementation of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Returns the current admin of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"admin()\")) == 0xf851a440\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Changes the admin of `proxy` to `newAdmin`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the current admin of `proxy`.\n     */\n    function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n        proxy.changeAdmin(newAdmin);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n        proxy.upgradeTo(implementation);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n     * {TransparentUpgradeableProxy-upgradeToAndCall}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgradeAndCall(\n        TransparentUpgradeableProxy proxy,\n        address implementation,\n        bytes memory data\n    ) public payable virtual onlyOwner {\n        proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n    }\n}\n"
    },
    "@openzeppelin/contracts/access/Ownable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/Context.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
    },
    "contracts/proxy/ContractProxy.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol';\nimport '@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol';\n"
    },
    "contracts/govers/ProviderRegistry.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/utils/cryptography/SignatureCheckerUpgradeable.sol';\nimport '../interfaces/IProviderRegistry.sol';\nimport './RouterWrapper.sol';\n\n/// @author Alexandas\n/// @dev provider registry contract\ncontract ProviderRegistry is IProviderRegistry, RouterWrapper, OwnableUpgradeable {\n\t/// @dev all providers\n\tmapping(address => bool) internal providers;\n\n\t/// @dev all provider wallets\n\tmapping(address => address) internal providerWallets;\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param router router contract address\n\tfunction initialize(address owner, IRouter router) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev add a provider\n\t/// @param provider address\n\tfunction addProvider(address provider) external onlyGovernance {\n\t\t_addProvider(provider);\n\t}\n\n\t/// @dev remove a provider\n\t/// @param provider address\n\tfunction removeProvider(address provider) external onlyGovernance {\n\t\t_removeProvider(provider);\n\t}\n\n\tfunction _addProvider(address provider) internal {\n\t\trequire(!isProvider(provider), 'ProviderRegistry: provider existed');\n\t\tproviders[provider] = true;\n\n\t\temit AddProvider(provider);\n\t}\n\n\tfunction _removeProvider(address provider) internal {\n\t\trequire(isProvider(provider), 'ProviderRegistry: nonexistent provider');\n\t\tdelete providers[provider];\n\n\t\temit RemoveProvider(provider);\n\t}\n\n\t/// @dev add provider wallet\n\t/// @param wallet wallet address\n\tfunction addWallet(address wallet) external onlyProvider {\n\t\t_addWallet(msg.sender, wallet);\n\t}\n\n\t/// @dev remove provider wallet\n\t/// @param wallet wallet address\n\tfunction removeWallet(address wallet) external onlyProvider {\n\t\t_removeWallet(msg.sender, wallet);\n\t}\n\n\tfunction _addWallet(address provider, address wallet) internal {\n\t\trequire(!providerWalletExists(provider), 'ProviderRegistry: provider wallet exists');\n\t\tproviderWallets[provider] = wallet;\n\n\t\temit AddProivderWallet(provider, wallet);\n\t}\n\n\tfunction _removeWallet(address provider, address wallet) internal {\n\t\trequire(providerWalletExists(provider), 'ProviderRegistry: nonexistent provider wallet');\n\t\tdelete providerWallets[provider];\n\t\temit RemoveProviderWallet(provider, wallet);\n\t}\n\n\t/// @dev return provider wallet exists\n\t/// @param provider address\n\t/// @return whether provider wallet exists\n\tfunction providerWalletExists(address provider) public view override returns (bool) {\n\t\treturn providerWallets[provider] != address(0);\n\t}\n\n\t/// @dev return provider wallet\n\t/// @param provider address\n\t/// @return provider wallet\n\tfunction providerWallet(address provider) public view override returns (address) {\n\t\trequire(providerWalletExists(provider), 'ProviderRegistry: nonexistent provider wallet');\n\t\treturn providerWallets[provider];\n\t}\n\n\t/// @dev return whether address is a provider\n\t/// @param provider address\n\t/// @return whether address is a provider\n\tfunction isProvider(address provider) public view override returns (bool) {\n\t\treturn providers[provider];\n\t}\n\n\t/// @dev return whether a valid signature\n\t/// @param provider address\n\t/// @param hash message hash\n\t/// @param signature provider signature for message hash\n\t/// @return whether signature is valid\n\tfunction isValidSignature(\n\t\taddress provider,\n\t\tbytes32 hash,\n\t\tbytes memory signature\n\t) public view returns (bool) {\n\t\trequire(isProvider(provider), 'ProviderRegistry: nonexistent provider');\n\t\treturn SignatureCheckerUpgradeable.isValidSignatureNow(provider, hash, signature);\n\t}\n}\n"
    },
    "contracts/govers/Governance.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\nimport './RouterWrapper.sol';\nimport '../interfaces/IGovernance.sol';\n\n/// @author Alexandas\n/// @dev Governace contract\ncontract Governance is IGovernance, RouterWrapper, OwnableUpgradeable {\n\tusing SafeMathUpgradeable for uint256;\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param router router contract\n\tfunction initialize(address owner, IRouter router) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev governance drip resource to provider\n\t/// @param provider provider address\n\t/// @param payloads resource amount payloads\n\tfunction drip(address provider, ResourceData.AmountPayload[] memory payloads) external override onlyOwner {\n\t\trequire(router.ProviderRegistry().isProvider(provider), 'Governance: nonexistent provider');\n\t\trequire(payloads.length > 0, 'Governance: empty payloads');\n\t\tfor (uint256 i = 0; i < payloads.length; i++) {\n\t\t\tResourceData.AmountPayload memory payload = payloads[i];\n\t\t\tResourceData.ResourceType resourceType = payload.resourceType;\n\t\t\tif (resourceType == ResourceData.ResourceType.BuildingTime) {\n\t\t\t\trequire(payload.amounts.length == 1, 'Governance: invalid amounts length for building time');\n\t\t\t\trouter.BuildingTimeController().allocateProvider(provider, payload.amounts[0]);\n\t\t\t} else if (resourceType == ResourceData.ResourceType.Bandwidth) {\n\t\t\t\trequire(payload.amounts.length == 1, 'Governance: invalid amounts length for bandwidth');\n\t\t\t\trouter.BandwidthController().allocateProvider(provider, payload.amounts[0]);\n\t\t\t} else if (resourceType == ResourceData.ResourceType.ARStorage) {\n\t\t\t\trequire(payload.amounts.length == 1, 'Governance: invalid amounts length for ar storage');\n\t\t\t\trouter.ARStorageController().allocateProvider(provider, payload.amounts[0]);\n\t\t\t} else if (resourceType == ResourceData.ResourceType.IPFSStorage) {\n\t\t\t\trequire(payload.amounts.length == 2, 'Governance: invalid amounts length for ipfs storage');\n\t\t\t\trouter.IPFSStorageController().allocateProvider(provider, payload.amounts[0], payload.amounts[1]);\n\t\t\t} else {\n\t\t\t\trevert('Governance: unknown resource type');\n\t\t\t}\n\t\t}\n\t\temit GovernanceDrip(provider);\n\t}\n\n\t/// @dev add a provider\n\t/// @param provider address\n\tfunction addProvider(address provider) external override onlyOwner {\n\t\trouter.ProviderRegistry().addProvider(provider);\n\t}\n\n\t/// @dev remove a provider\n\t/// @param provider address\n\tfunction removeProvider(address provider) external override onlyOwner {\n\t\trouter.ProviderRegistry().removeProvider(provider);\n\t}\n}\n"
    },
    "contracts/govers/ProviderController.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol';\n\nimport './RouterWrapper.sol';\nimport '../access/Pauser.sol';\n\n/// @author Alexandas\n/// @dev provider controller contract\ncontract ProviderController is IProviderController, EIP712Upgradeable, Pauser, RouterWrapper {\n\tusing SafeMathUpgradeable for uint256;\n\t/// @dev all accounts\n\tmapping(address => mapping(bytes32 => bool)) internal accounts;\n\n\t/// @dev all wallets\n\tmapping(address => mapping(bytes32 => address)) internal wallets;\n\n\t/// @dev keccak256(\"Wallet(address provider,bytes32 account,address wallet)\")\n\tbytes32 public override walletTypesHash;\n\n\tconstructor() initializer {}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param pauser contract pauser\n\t/// @param router router contract address\n\tfunction initialize(\n\t\taddress owner,\n\t\taddress pauser,\n\t\tstring memory name,\n\t\tstring memory version,\n\t\tstring memory walletTypes,\n\t\tIRouter router\n\t) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Pauser(pauser);\n\t\t__EIP712_init(name, version);\n\t\t__Init_Wallet_Types_Hash(walletTypes);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev initialize wallet types hash\n\t/// @param types wallet types\n\tfunction __Init_Wallet_Types_Hash(string memory types) internal onlyInitializing {\n\t\t_setWalletTypesHash(keccak256(bytes(types)));\n\t}\n\n\t/// @dev register account\n\t/// @param account user account\n\tfunction registerAccount(bytes32 account) external override onlyProvider {\n\t\t_registerAccount(msg.sender, account);\n\t}\n\n\t/// @dev register multiple account\n\t/// @param accounts user accounts\n\tfunction registerMult(bytes32[] memory accounts) external override onlyProvider {\n\t\tfor (uint256 i = 0; i < accounts.length; i++) {\n\t\t\t_registerAccount(msg.sender, accounts[i]);\n\t\t}\n\t}\n\n\tfunction _registerAccount(address provider, bytes32 account) internal {\n\t\trequire(!accountExists(provider, account), 'ProviderController: account exists');\n\t\trequire(router.ProviderRegistry().isProvider(msg.sender), 'ProviderController: nonexistent provider');\n\t\taccounts[provider][account] = true;\n\n\t\temit AccountRegistered(provider, account);\n\t}\n\n\t/// @dev return whether the account exists\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return whether account exists\n\tfunction accountExists(address provider, bytes32 account) public view override returns (bool) {\n\t\trequire(router.ProviderRegistry().isProvider(provider), 'ProviderController: nonexistent provider');\n\t\treturn accounts[provider][account];\n\t}\n\n\t/// @dev provider drip resource to multiple accounts\n\t/// @param accounts user accounts\n\t/// @param payloads resource amount payloads\n\tfunction dripMult(\n\t\tbytes32[] memory accounts,\n\t\tResourceData.AmountPayload[][] memory payloads\n\t) external override onlyProvider {\n\t\trequire(accounts.length > 0, 'ProviderController: invalid accounts length');\n\t\trequire(payloads.length > 0, 'ProviderController: invalid payloads length');\n\t\trequire(accounts.length == payloads.length, 'ProviderController: inconsitent parameter length');\n\t\tfor (uint256 i = 0; i < accounts.length; i++) {\n\t\t\t_drip(msg.sender, accounts[i], payloads[i]);\n\t\t}\n\t}\n\n\t/// @dev provider drip resource to user account\n\t/// @param account user account\n\t/// @param payloads resource amount payloads\n\tfunction drip(\n\t\tbytes32 account,\n\t\tResourceData.AmountPayload[] memory payloads\n\t) external override onlyProvider {\n\t\t_drip(msg.sender, account, payloads);\n\t}\n\n\tfunction _drip(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tResourceData.AmountPayload[] memory payloads\n\t) internal {\n\t\trequire(accountExists(provider, account), 'AccountRegistry: account exists');\n\t\trequire(router.ProviderRegistry().isProvider(provider), 'ProviderController: nonexistent provider');\n\t\trequire(payloads.length > 0, 'ProviderController: empty payloads');\n\t\tfor (uint256 i = 0; i < payloads.length; i++) {\n\t\t\tResourceData.AmountPayload memory payload = payloads[i];\n\t\t\tResourceData.ResourceType resourceType = payload.resourceType;\n\t\t\tif (resourceType == ResourceData.ResourceType.BuildingTime) {\n\t\t\t\trequire(payload.amounts.length == 1, 'ProviderController: invalid amounts length for building time');\n\t\t\t\trouter.BuildingTimeController().drip(provider, account, payload.amounts[0]);\n\t\t\t} else if (resourceType == ResourceData.ResourceType.Bandwidth) {\n\t\t\t\trequire(payload.amounts.length == 1, 'ProviderController: invalid amounts length for bandwidth');\n\t\t\t\trouter.BandwidthController().drip(provider, account, payload.amounts[0]);\n\t\t\t} else if (resourceType == ResourceData.ResourceType.ARStorage) {\n\t\t\t\trequire(payload.amounts.length == 1, 'ProviderController: invalid amounts length for ar storage');\n\t\t\t\trouter.ARStorageController().drip(provider, account, payload.amounts[0]);\n\t\t\t} else if (resourceType == ResourceData.ResourceType.IPFSStorage) {\n\t\t\t\trequire(payload.amounts.length == 2, 'ProviderController: invalid amounts length for ipfs storage');\n\t\t\t\trouter.IPFSStorageController().drip(provider, account, payload.amounts[0], payload.amounts[1]);\n\t\t\t} else {\n\t\t\t\trevert('ProviderController: unknown resource type');\n\t\t\t}\n\t\t}\n\t\temit ProviderDripped(provider, account);\n\t}\n\n\t/// @dev provider register and drip resource for multiple accounts\n\t/// @param accounts user accounts\n\t/// @param payloads resource amount payloads\n\tfunction registerAndDripMult(\n\t\tbytes32[] memory accounts,\n\t\tResourceData.AmountPayload[][] memory payloads\n\t) external override onlyProvider {\n\t\trequire(accounts.length > 0, 'ProviderController: invalid accounts length');\n\t\trequire(payloads.length > 0, 'ProviderController: invalid payloads length');\n\t\trequire(accounts.length == payloads.length, 'ProviderController: inconsitent parameter length');\n\t\tfor (uint256 i = 0; i < accounts.length; i++) {\n\t\t\t_registerAccount(msg.sender, accounts[i]);\n\t\t\t_drip(msg.sender, accounts[i], payloads[i]);\n\t\t}\n\t}\n\n\t/// @dev initialize wallet for the given account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param wallet account wallet\n\t/// @param signature provider signature\n\tfunction initWallet(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\taddress wallet,\n\t\tbytes memory signature\n\t) external override {\n\t\trequire(msg.sender == wallet, 'ProviderController: caller in not the wallet');\n\t\trequire(accountExists(provider, account), 'ProviderController: nonexistent account');\n\t\trequire(!walletExists(provider, account), 'ProviderController: wallet exists');\n\t\tbytes32 hash = hashTypedDataV4ForWallet(provider, account, wallet);\n\t\trequire(router.ProviderRegistry().isValidSignature(provider, hash, signature), 'ProviderController: invalid signature');\n\t\t_transferWallet(provider, account, address(0), wallet);\n\t}\n\n\t/// @dev transfer wallet for the account\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param newWallet account wallet\n\tfunction transferWallet(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\taddress newWallet\n\t) external override {\n\t\taddress wallet = walletOf(provider, account);\n\t\trequire(msg.sender == wallet, 'ProviderController: caller is not the current wallet');\n\t\t_transferWallet(provider, account, wallet, newWallet);\n\t}\n\n\tfunction walletOf(address provider, bytes32 account) public view override returns (address) {\n\t\trequire(walletExists(provider, account), 'ProviderController: nonexistent wallet');\n\t\treturn wallets[provider][account];\n\t}\n\n\tfunction _transferWallet(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\taddress from,\n\t\taddress to\n\t) internal {\n\t\twallets[provider][account] = to;\n\t\temit WalletTransferred(provider, account, from, to);\n\t}\n\n\t/// @dev return recharge hash typed v4\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param wallet wallet address\n\t/// @return wallet hash typed v4\n\tfunction hashTypedDataV4ForWallet(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\taddress wallet\n\t) public view returns (bytes32) {\n\t\treturn _hashTypedDataV4(hashWalletTypes(provider, account, wallet));\n\t}\n\n\t/// @dev return recharge typed hash\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param wallet wallet address\n\t/// @return wallet hash typed v4\n\tfunction hashWalletTypes(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\taddress wallet\n\t) public view returns (bytes32) {\n\t\treturn keccak256(abi.encode(walletTypesHash, provider, account, wallet));\n\t}\n\n\tfunction _setWalletTypesHash(bytes32 hash) internal {\n\t\twalletTypesHash = hash;\n\t\temit WalletTypesHashUpdated(hash);\n\t}\n\n\t/// @dev return whether wallet exists\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @return whether wallet exists\n\tfunction walletExists(address provider, bytes32 account) public view override returns (bool) {\n\t\treturn wallets[provider][account] != address(0);\n\t}\n}\n"
    },
    "contracts/ipfs/ContentTracer.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity >=0.8.0;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\nimport '@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol';\nimport '../govers/RouterWrapper.sol';\n\n/// @author Alexandas\n/// @dev IPFS content tracer\ncontract ContentTracer is RouterWrapper, OwnableUpgradeable {\n\tusing SafeMathUpgradeable for uint256;\n\n\tstruct ContentMeta {\n\t\tuint256 size;\n\t\tuint256 count;\n\t}\n\n\t/// @dev ipfs content content meta\n\tmapping(address => mapping(bytes32 => mapping(string => ContentMeta))) public metas;\n\n\t/// @dev emit when ipfs content inserted\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param content ipfs content\n\t/// @param size ipfs content size\n\t/// @param count ipfs content count\n\t/// @param expiration ipfs content expiration\n\tevent Insert(address provider, bytes32 account, string content, uint256 size, uint256 count, uint256 expiration);\n\n\t/// @dev emit when ipfs content removed\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param content ipfs content\n\t/// @param size ipfs content size\n\t/// @param count ipfs content count\n\tevent Remove(address provider, bytes32 account, string content, uint256 size, uint256 count);\n\n\tmodifier nonSize(uint256 size) {\n\t\trequire(size > 0, 'ContentTracer: zero size.');\n\t\t_;\n\t}\n\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param router router contract address\n\tfunction initialize(address owner, IRouter router) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Router(router);\n\t}\n\n\t/// @dev insert multiple ipfs content for accounts\n\t/// @param accounts array of user account\n\t/// @param contents array of ipfs contents\n\t/// @param sizes array of ipfs content size\n\t/// @param counts array of ipfs content count\n\tfunction insertMult(\n\t\tbytes32[] memory accounts,\n\t\tstring[] memory contents,\n\t\tuint256[] memory sizes,\n\t\tuint256[] memory counts\n\t) external onlyProvider {\n\t\trequire(accounts.length == contents.length, 'ContentTracer: Invalid parameter length.');\n\t\trequire(accounts.length == sizes.length, 'ContentTracer: Invalid parameter length.');\n\t\trequire(accounts.length == counts.length, 'ContentTracer: Invalid parameter length.');\n\n\t\tfor (uint256 i = 0; i < accounts.length; i++) {\n\t\t\t_insert(msg.sender, accounts[i], contents[i], sizes[i], counts[i]);\n\t\t}\n\t}\n\n\t/// @dev insert ipfs content\n\t/// @param account user account\n\t/// @param content ipfs content\n\t/// @param size ipfs account size\n\t/// @param count array of ipfs content count\n\tfunction insert(\n\t\tbytes32 account,\n\t\tstring memory content,\n\t\tuint256 size,\n\t\tuint256 count\n\t) public nonSize(size) onlyProvider {\n\t\t_insert(msg.sender, account, content, size, count);\n\t}\n\n\tfunction _insert(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tstring memory content,\n\t\tuint256 size,\n\t\tuint256 count\n\t) internal nonSize(size) {\n\t\tIIPFSStorageController controller = router.IPFSStorageController();\n\t\trequire(!exists(provider, account, content), 'ContentTracer: content exists');\n\t\trequire(!controller.isExpired(provider, account), 'ContentTracer: account expired');\n\t\tmetas[provider][account][content] = ContentMeta(size, count);\n\n\t\temit Insert(provider, account, content, size, count, controller.expiredAt(provider, account));\n\t}\n\n\t/// @dev remove ipfs content\n\t/// @param accounts array of user account\n\t/// @param contents array of ipfs contents\n\tfunction removeMult(bytes32[] memory accounts, string[] memory contents) external onlyProvider {\n\t\trequire(accounts.length == contents.length, 'ContentTracer: Invalid parameter length');\n\t\tfor (uint256 i = 0; i < accounts.length; i++) {\n\t\t\t_remove(msg.sender, accounts[i], contents[i]);\n\t\t}\n\t}\n\n\t/// @dev remove ipfs content\n\t/// @param account user account\n\t/// @param content ipfs content\n\tfunction remove(bytes32 account, string memory content) public onlyProvider {\n\t\t_remove(msg.sender, account, content);\n\t}\n\n\tfunction _remove(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tstring memory content\n\t) internal {\n\t\trequire(exists(provider, account, content), 'ContentTracer: nonexistent content');\n\t\tContentMeta memory meta = metas[provider][account][content];\n\t\tdelete metas[provider][account][content];\n\n\t\temit Remove(provider, account, content, meta.size, meta.count);\n\t}\n\n\t/// @dev return whether ipfs content exists in provider\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param content ipfs content\n\t/// @return ipfs ipfs content exists\n\tfunction exists(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tstring memory content\n\t) public view returns (bool) {\n\t\treturn metas[provider][account][content].size != 0;\n\t}\n\n\t/// @dev return ipfs content size\n\t/// @param provider provider address\n\t/// @param account user account\n\t/// @param content ipfs content\n\t/// @return ipfs ipfs content size\n\tfunction size(\n\t\taddress provider,\n\t\tbytes32 account,\n\t\tstring memory content\n\t) public view returns (uint256) {\n\t\trequire(router.ProviderRegistry().isProvider(provider), 'ContentTracer: nonexistent provider');\n\t\trequire(exists(provider, account, content), 'ContentTracer: nonexistent content');\n\t\treturn metas[provider][account][content].size;\n\t}\n}\n"
    },
    "contracts/resources/controllers/normal/ARStorageController.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '../NormalResourceController.sol';\n\n/// @author Alexandas\n/// @dev AR storage controller controller\ncontract ARStorageController is NormalResourceController {\n\t/// @dev proxy initialize function\n\t/// @param owner contract owner\n\t/// @param router router contract\n\tfunction initialize(\n\t\taddress owner,\n\t\tIRouter router\n\t) external initializer {\n\t\t_transferOwnership(owner);\n\t\t__Init_Router(router);\n\t}\n}\n"
    },
    "contracts/resources/interfaces/IResource.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSE\n\npragma solidity >=0.8.0;\n\nimport '../../libraries/ResourceData.sol';\n\n/// @author Alexandas\n/// @dev resource interface\ninterface IResource {\n\n\t/// @dev emit when resource type updated\n\t/// @param resourceType resource type\n\tevent ResourceTypeUpdated(ResourceData.ResourceType resourceType);\n\n\t/// @dev return resource type\n\tfunction resourceType() external view returns (ResourceData.ResourceType);\n\n}\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 200,
      "details": {
        "yul": false
      }
    },
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata",
          "devdoc",
          "userdoc",
          "storageLayout",
          "evm.gasEstimates"
        ],
        "": [
          "ast"
        ]
      }
    },
    "metadata": {
      "useLiteralContent": true
    }
  }
}