Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Forwarder
- Optimization enabled
- true
- Compiler version
- v0.8.24+commit.e11b9ed9
- Optimization runs
- 100
- EVM Version
- paris
- Verified at
- 2024-07-31T16:00:23.540832Z
contracts/xai-subsidy/Forwarder.sol
// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.22;import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";contract Forwarder is Initializable {using ECDSA for bytes32;bytes32 public DOMAIN_SEPARATOR;bytes32 public constant FORWARD_REQUEST_TYPEHASH =keccak256("ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data)");// Mapping to store nonces for each sendermapping(address => uint256) public nonces;struct ForwardRequest {address from; // an externally owned account making the requestaddress to; // destination address, in this case the Receiver Contractuint256 value; // ETH Amount to transfer to destinationuint256 gas; // gas limit for executionuint256 nonce; // the users nonce for this requestbytes data; // the data to be sent to the destination}function initialize() public initializer {uint256 chainId;assembly {chainId := chainid()}DOMAIN_SEPARATOR = keccak256(abi.encode(keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),keccak256(bytes("Forwarder")), // Name of the contractkeccak256(bytes("1")), // VersionchainId, // Chain IDaddress(this) // Address of the contract));}function verify(ForwardRequest calldata request, bytes calldata signature) public view returns (bool) {
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)pragma solidity ^0.8.2;import "../../utils/AddressUpgradeable.sol";/*** @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.** The initialization functions use a version number. Once a version number is used, it is consumed and cannot be* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in* case an upgrade adds a module that needs to be initialized.** For example:** [.hljs-theme-light.nopadding]* ```solidity* contract MyToken is ERC20Upgradeable {* function initialize() initializer public {* __ERC20_init("MyToken", "MTK");* }* }** contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {* function initializeV2() reinitializer(2) public {* __ERC20Permit_init("MyToken");* }* }* ```** TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.** CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.** [CAUTION]
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)pragma solidity ^0.8.1;/*** @dev Collection of functions related to the address type*/library AddressUpgradeable {/*** @dev Returns true if `account` is a contract.** [IMPORTANT]* ====* It is unsafe to assume that an address for which this function returns* false is an externally-owned account (EOA) and not a contract.** Among others, `isContract` will return false for the following* types of addresses:** - an externally-owned account* - a contract in construction* - an address where a contract will be created* - an address where a contract lived, but was destroyed** Furthermore, `isContract` will also return true if the target contract within* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,* which only has an effect at the end of a transaction.* ====** [IMPORTANT]* ====* You shouldn't rely on `isContract` to protect against flash loan attacks!** Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract* constructor.* ====*/function isContract(address account) internal view returns (bool) {// This method relies on extcodesize/address.code.length, which returns 0
@openzeppelin/contracts/utils/Strings.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)pragma solidity ^0.8.0;import "./math/Math.sol";import "./math/SignedMath.sol";/*** @dev String operations.*/library Strings {bytes16 private constant _SYMBOLS = "0123456789abcdef";uint8 private constant _ADDRESS_LENGTH = 20;/*** @dev Converts a `uint256` to its ASCII `string` decimal representation.*/function toString(uint256 value) internal pure returns (string memory) {unchecked {uint256 length = Math.log10(value) + 1;string memory buffer = new string(length);uint256 ptr;/// @solidity memory-safe-assemblyassembly {ptr := add(buffer, add(32, length))}while (true) {ptr--;/// @solidity memory-safe-assemblyassembly {mstore8(ptr, byte(mod(value, 10), _SYMBOLS))}value /= 10;if (value == 0) break;}return buffer;}}/**
@openzeppelin/contracts/utils/cryptography/ECDSA.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)pragma solidity ^0.8.0;import "../Strings.sol";/*** @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.** These functions can be used to verify that a message was signed by the holder* of the private keys of a given address.*/library ECDSA {enum RecoverError {NoError,InvalidSignature,InvalidSignatureLength,InvalidSignatureS,InvalidSignatureV // Deprecated in v4.8}function _throwError(RecoverError error) private pure {if (error == RecoverError.NoError) {return; // no error: do nothing} else if (error == RecoverError.InvalidSignature) {revert("ECDSA: invalid signature");} else if (error == RecoverError.InvalidSignatureLength) {revert("ECDSA: invalid signature length");} else if (error == RecoverError.InvalidSignatureS) {revert("ECDSA: invalid signature 's' value");}}/*** @dev Returns the address that signed a hashed message (`hash`) with* `signature` or error string. This address can then be used for verification purposes.** The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:* this function rejects them by requiring the `s` value to be in the lower* half order, and the `v` value to be either 27 or 28.
@openzeppelin/contracts/utils/math/Math.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)pragma solidity ^0.8.0;/*** @dev Standard math utilities missing in the Solidity language.*/library Math {enum Rounding {Down, // Toward negative infinityUp, // Toward infinityZero // Toward zero}/*** @dev Returns the largest of two numbers.*/function max(uint256 a, uint256 b) internal pure returns (uint256) {return a > b ? a : b;}/*** @dev Returns the smallest of two numbers.*/function min(uint256 a, uint256 b) internal pure returns (uint256) {return a < b ? a : b;}/*** @dev Returns the average of two numbers. The result is rounded towards* zero.*/function average(uint256 a, uint256 b) internal pure returns (uint256) {// (a + b) / 2 can overflow.return (a & b) + (a ^ b) / 2;}/*** @dev Returns the ceiling of the division of two numbers.*
@openzeppelin/contracts/utils/math/SignedMath.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)pragma solidity ^0.8.0;/*** @dev Standard signed math utilities missing in the Solidity language.*/library SignedMath {/*** @dev Returns the largest of two signed numbers.*/function max(int256 a, int256 b) internal pure returns (int256) {return a > b ? a : b;}/*** @dev Returns the smallest of two signed numbers.*/function min(int256 a, int256 b) internal pure returns (int256) {return a < b ? a : b;}/*** @dev Returns the average of two signed numbers without overflow.* The result is rounded towards zero.*/function average(int256 a, int256 b) internal pure returns (int256) {// Formula from the book "Hacker's Delight"int256 x = (a & b) + ((a ^ b) >> 1);return x + (int256(uint256(x) >> 255) & (a ^ b));}/*** @dev Returns the absolute unsigned value of a signed value.*/function abs(int256 n) internal pure returns (uint256) {unchecked {// must be unchecked in order to support `n = type(int256).min`return uint256(n >= 0 ? n : -n);}
Compiler Settings
{"viaIR":true,"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":100,"enabled":true,"details":{"yulDetails":{"optimizerSteps":"u"}}},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"event","name":"Initialized","inputs":[{"type":"uint8","name":"version","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DOMAIN_SEPARATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"FORWARD_REQUEST_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bool","name":"","internalType":"bool"},{"type":"bytes","name":"","internalType":"bytes"}],"name":"execute","inputs":[{"type":"tuple","name":"request","internalType":"struct Forwarder.ForwardRequest","components":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"uint256","name":"gas","internalType":"uint256"},{"type":"uint256","name":"nonce","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"bytes","name":"signature","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nonces","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"verify","inputs":[{"type":"tuple","name":"request","internalType":"struct Forwarder.ForwardRequest","components":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"uint256","name":"gas","internalType":"uint256"},{"type":"uint256","name":"nonce","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"bytes","name":"signature","internalType":"bytes"}]}]
Contract Creation Code
0x60806040523461001a57604051610e2c6100208239610e2c90f35b600080fdfe6080604052600436101561001257600080fd5b60003560e01c80633644e5151461007257806347153f821461006d5780637ecebe00146100685780638129fc1c14610063578063956309681461005e5763bf5d3bdb0361008257610312565b6102f7565b6102b6565b61029b565b6101e1565b6100b2565b600091031261008257565b600080fd5b610092916008021c81565b90565b906100929154610087565b61009260006001610095565b9052565b565b34610082576100c2366004610077565b6100dd6100cd6100a0565b6040519182918290815260200190565b0390f35b908160c09103126100825790565b909182601f830112156100825781359167ffffffffffffffff831161008257602001926001830284011161008257565b91909160408184031261008257803567ffffffffffffffff811161008257836101499183016100e1565b92602082013567ffffffffffffffff81116100825761016892016100ef565b9091565b60005b83811061017f5750506000910152565b818101518382015260200161016f565b6101b06101b96020936101c3936101a4815190565b80835293849260200190565b9586910161016c565b601f01601f191690565b0190565b90151581526040602082018190526100929291019061018f565b6101f56101ef36600461011f565b9161060c565b906100dd61020260405190565b928392836101c7565b6001600160a01b031690565b6102208161020b565b0361008257565b905035906100b082610217565b906020828203126100825761009291610227565b6100929061020b906001600160a01b031682565b61009290610248565b6100929061025c565b9061027890610265565b600052602052604060002090565b600061029661009292600261026e565b610095565b34610082576100dd6100cd6102b1366004610234565b610286565b34610082576102c6366004610077565b6102ce610a81565b604051005b7fdd8f4b70b0f4393e889bd39128a30628a78b61816a9eb8199759e7a349657e4890565b3461008257610307366004610077565b6100dd6100cd6102d3565b34610082576100dd61032e61032836600461011f565b91610b51565b60405191829182901515815260200190565b80610220565b3561009281610340565b6020808252600d908201526c496e76616c69642076616c756560981b604082015260600190565b1561037e57565b60405162461bcd60e51b81528061039760048201610350565b0390fd5b602080825260119082015270496e76616c6964207369676e617475726560781b604082015260600190565b156103cd57565b60405162461bcd60e51b8152806103976004820161039b565b3561009281610217565b6100929081565b61009290546103f0565b634e487b7160e01b600052601160045260246000fd5b60001981146104265760010190565b610401565b90600019905b9181191691161790565b6100926100926100929290565b9061045861009261045f9261043b565b825461042b565b9055565b903590601e193682900301821215610082570180359067ffffffffffffffff8211610082576020019136829003831361008257565b90826000939282370152565b90916101c39083908093610498565b60601b90565b610092906104b3565b6104ce6100ac9161020b565b6104b9565b6104e490601494936101c3936104a4565b80926104c2565b634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff82111761052357604052565b6104eb565b906100b061053560405190565b9283610501565b67ffffffffffffffff811161052357602090601f01601f19160190565b9061056b6105668361053c565b610528565b918252565b3d1561058a5761057f3d610559565b903d6000602084013e565b606090565b634e487b7160e01b600052601260045260246000fd5b906105af565b9190565b9081156105ba570490565b61058f565b602080825260139082015272119d5b98dd1a5bdb98d85b1b0819985a5b1959606a1b604082015260600190565b156105f357565b60405162461bcd60e51b815280610397600482016105bf565b92916000916106486106438493610621600090565b50604088019361063d61063661009287610346565b3414610377565b88610b51565b6103c6565b81850161067861066161065a836103e6565b600261026e565b61067261066d826103f7565b610417565b90610448565b610684602087016103e6565b9560608101966106b86106df6106b06106a561069f8c610346565b97610346565b9460a0810190610463565b9290956103e6565b916106d36106c560405190565b9384926020840198896104d3565b86810382520382610501565b5193f16106ea610570565b9261070e6105ab6100926106fe5a94610346565b610708603f61043b565b906105a5565b111561071d576105ab816105ec565bfe5b6100929060081c5b60ff1690565b610092905461071f565b61009290610727565b6100929054610737565b6107276100926100929290565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b156107ac57565b60405162461bcd60e51b81528061039760048201610757565b9060ff90610431565b6107276100926100929260ff1690565b906107ee61009261045f926107ce565b82546107c5565b9061ff009060081b610431565b151590565b9061081761009261045f92610802565b82546107f5565b6100ac9061074a565b6020810192916100b0919061081e565b610848610844600061072d565b1590565b8080610923575b80156108de575b61085f906107a5565b8061087461086d600161074a565b60006107de565b6108cd575b6108816109e5565b61088757565b610892600080610807565b7f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986108bc60405190565b806108c8600182610827565b0390a1565b6108d960016000610807565b610879565b506108f36108446108ee30610265565b610c9a565b8015610856575061085f6109076000610740565b61091b610914600161074a565b9160ff1690565b149050610856565b5061092e6000610740565b61093b610914600161074a565b1061084f565b61094b6009610559565b682337b93bb0b93232b960b91b602082015290565b610092610941565b6109726001610559565b603160f81b602082015290565b610092610968565b6100ac9061020b565b909594926100b0946109c26109c9926109bb6080966109b460a088019c6000890152565b6020870152565b6040850152565b6060830152565b0190610987565b906104586109e061045f92610092565b610092565b6100b06109f0610960565b610a026109fb825190565b9160200190565b20610a6e610a0e61097f565b610a196109fb825190565b2091610a2430610265565b92610a62610a3160405190565b948593602085019346917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f86610990565b90810382520382610501565b610a796109fb825190565b2060016109d0565b6100b0610837565b90929192610a996105668261053c565b9381855281830111610082576100b0916020850190610498565b610092913691610a89565b90815260e08101979695909490939092909160208601610add91610987565b60408501610aea91610987565b6060840152608083015260a082015260c00152565b6020809392610b1c61056b6101c39461190160f01b815260020190565b01918252565b634e487b7160e01b600052602160045260246000fd5b60051115610b4257565b610b22565b906100b082610b38565b9190610c51610c5792610b62600090565b50610a62610c3f610b7360016103f7565b87610c1b817fdd8f4b70b0f4393e889bd39128a30628a78b61816a9eb8199759e7a349657e48610a62610bb16020610baa856103e6565b94016103e6565b948d610bbf60408201610346565b91610bf7610bf1610be6610be161065a610bdb60608801610346565b956103e6565b6103f7565b9360a0810190610463565b90610ab3565b610c026109fb825190565b2092610c0d60405190565b988997602089019788610abe565b610c266109fb825190565b2090610c3160405190565b938492602084019283610aff565b610c4a6109fb825190565b2092610ab3565b90610cc2565b610c6d610c676000949394610b47565b91610b47565b14610c79575050600090565b610c90610c8b6000610c9693016103e6565b61020b565b9161020b565b1490565b3b610ca86105ab600061043b565b1190565b61020b6100926100929290565b61009290610cac565b908051610cd26105ab604161043b565b03610cf457610168916020820151906060604084015193015160001a90610d4f565b5050610d006000610cb9565b90600290565b6100929061043b565b610d3f6100b094610d38606094989795610d2e608086019a6000870152565b60ff166020850152565b6040830152565b0152565b6040513d6000823e3d90fd5b919291610d5b83610d06565b610d7d6105ab6fa2a8918ca85bafe22016d0b997e4df60600160ff1b0361043b565b11610de257610d9d600093602095610d9460405190565b94859485610d0f565b838052039060015afa15610ddd57600051610db86000610cb9565b610dc18161020b565b610dca8361020b565b14610dd6575090600090565b9160019150565b610d43565b50505050610df06000610cb9565b9060039056fea264697066735822122026eaa5afe824c41e3c871d14cc70209049f891f5c3dfafabfa6792c058934de564736f6c63430008180033
Deployed ByteCode
0x6080604052600436101561001257600080fd5b60003560e01c80633644e5151461007257806347153f821461006d5780637ecebe00146100685780638129fc1c14610063578063956309681461005e5763bf5d3bdb0361008257610312565b6102f7565b6102b6565b61029b565b6101e1565b6100b2565b600091031261008257565b600080fd5b610092916008021c81565b90565b906100929154610087565b61009260006001610095565b9052565b565b34610082576100c2366004610077565b6100dd6100cd6100a0565b6040519182918290815260200190565b0390f35b908160c09103126100825790565b909182601f830112156100825781359167ffffffffffffffff831161008257602001926001830284011161008257565b91909160408184031261008257803567ffffffffffffffff811161008257836101499183016100e1565b92602082013567ffffffffffffffff81116100825761016892016100ef565b9091565b60005b83811061017f5750506000910152565b818101518382015260200161016f565b6101b06101b96020936101c3936101a4815190565b80835293849260200190565b9586910161016c565b601f01601f191690565b0190565b90151581526040602082018190526100929291019061018f565b6101f56101ef36600461011f565b9161060c565b906100dd61020260405190565b928392836101c7565b6001600160a01b031690565b6102208161020b565b0361008257565b905035906100b082610217565b906020828203126100825761009291610227565b6100929061020b906001600160a01b031682565b61009290610248565b6100929061025c565b9061027890610265565b600052602052604060002090565b600061029661009292600261026e565b610095565b34610082576100dd6100cd6102b1366004610234565b610286565b34610082576102c6366004610077565b6102ce610a81565b604051005b7fdd8f4b70b0f4393e889bd39128a30628a78b61816a9eb8199759e7a349657e4890565b3461008257610307366004610077565b6100dd6100cd6102d3565b34610082576100dd61032e61032836600461011f565b91610b51565b60405191829182901515815260200190565b80610220565b3561009281610340565b6020808252600d908201526c496e76616c69642076616c756560981b604082015260600190565b1561037e57565b60405162461bcd60e51b81528061039760048201610350565b0390fd5b602080825260119082015270496e76616c6964207369676e617475726560781b604082015260600190565b156103cd57565b60405162461bcd60e51b8152806103976004820161039b565b3561009281610217565b6100929081565b61009290546103f0565b634e487b7160e01b600052601160045260246000fd5b60001981146104265760010190565b610401565b90600019905b9181191691161790565b6100926100926100929290565b9061045861009261045f9261043b565b825461042b565b9055565b903590601e193682900301821215610082570180359067ffffffffffffffff8211610082576020019136829003831361008257565b90826000939282370152565b90916101c39083908093610498565b60601b90565b610092906104b3565b6104ce6100ac9161020b565b6104b9565b6104e490601494936101c3936104a4565b80926104c2565b634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff82111761052357604052565b6104eb565b906100b061053560405190565b9283610501565b67ffffffffffffffff811161052357602090601f01601f19160190565b9061056b6105668361053c565b610528565b918252565b3d1561058a5761057f3d610559565b903d6000602084013e565b606090565b634e487b7160e01b600052601260045260246000fd5b906105af565b9190565b9081156105ba570490565b61058f565b602080825260139082015272119d5b98dd1a5bdb98d85b1b0819985a5b1959606a1b604082015260600190565b156105f357565b60405162461bcd60e51b815280610397600482016105bf565b92916000916106486106438493610621600090565b50604088019361063d61063661009287610346565b3414610377565b88610b51565b6103c6565b81850161067861066161065a836103e6565b600261026e565b61067261066d826103f7565b610417565b90610448565b610684602087016103e6565b9560608101966106b86106df6106b06106a561069f8c610346565b97610346565b9460a0810190610463565b9290956103e6565b916106d36106c560405190565b9384926020840198896104d3565b86810382520382610501565b5193f16106ea610570565b9261070e6105ab6100926106fe5a94610346565b610708603f61043b565b906105a5565b111561071d576105ab816105ec565bfe5b6100929060081c5b60ff1690565b610092905461071f565b61009290610727565b6100929054610737565b6107276100926100929290565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b156107ac57565b60405162461bcd60e51b81528061039760048201610757565b9060ff90610431565b6107276100926100929260ff1690565b906107ee61009261045f926107ce565b82546107c5565b9061ff009060081b610431565b151590565b9061081761009261045f92610802565b82546107f5565b6100ac9061074a565b6020810192916100b0919061081e565b610848610844600061072d565b1590565b8080610923575b80156108de575b61085f906107a5565b8061087461086d600161074a565b60006107de565b6108cd575b6108816109e5565b61088757565b610892600080610807565b7f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986108bc60405190565b806108c8600182610827565b0390a1565b6108d960016000610807565b610879565b506108f36108446108ee30610265565b610c9a565b8015610856575061085f6109076000610740565b61091b610914600161074a565b9160ff1690565b149050610856565b5061092e6000610740565b61093b610914600161074a565b1061084f565b61094b6009610559565b682337b93bb0b93232b960b91b602082015290565b610092610941565b6109726001610559565b603160f81b602082015290565b610092610968565b6100ac9061020b565b909594926100b0946109c26109c9926109bb6080966109b460a088019c6000890152565b6020870152565b6040850152565b6060830152565b0190610987565b906104586109e061045f92610092565b610092565b6100b06109f0610960565b610a026109fb825190565b9160200190565b20610a6e610a0e61097f565b610a196109fb825190565b2091610a2430610265565b92610a62610a3160405190565b948593602085019346917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f86610990565b90810382520382610501565b610a796109fb825190565b2060016109d0565b6100b0610837565b90929192610a996105668261053c565b9381855281830111610082576100b0916020850190610498565b610092913691610a89565b90815260e08101979695909490939092909160208601610add91610987565b60408501610aea91610987565b6060840152608083015260a082015260c00152565b6020809392610b1c61056b6101c39461190160f01b815260020190565b01918252565b634e487b7160e01b600052602160045260246000fd5b60051115610b4257565b610b22565b906100b082610b38565b9190610c51610c5792610b62600090565b50610a62610c3f610b7360016103f7565b87610c1b817fdd8f4b70b0f4393e889bd39128a30628a78b61816a9eb8199759e7a349657e48610a62610bb16020610baa856103e6565b94016103e6565b948d610bbf60408201610346565b91610bf7610bf1610be6610be161065a610bdb60608801610346565b956103e6565b6103f7565b9360a0810190610463565b90610ab3565b610c026109fb825190565b2092610c0d60405190565b988997602089019788610abe565b610c266109fb825190565b2090610c3160405190565b938492602084019283610aff565b610c4a6109fb825190565b2092610ab3565b90610cc2565b610c6d610c676000949394610b47565b91610b47565b14610c79575050600090565b610c90610c8b6000610c9693016103e6565b61020b565b9161020b565b1490565b3b610ca86105ab600061043b565b1190565b61020b6100926100929290565b61009290610cac565b908051610cd26105ab604161043b565b03610cf457610168916020820151906060604084015193015160001a90610d4f565b5050610d006000610cb9565b90600290565b6100929061043b565b610d3f6100b094610d38606094989795610d2e608086019a6000870152565b60ff166020850152565b6040830152565b0152565b6040513d6000823e3d90fd5b919291610d5b83610d06565b610d7d6105ab6fa2a8918ca85bafe22016d0b997e4df60600160ff1b0361043b565b11610de257610d9d600093602095610d9460405190565b94859485610d0f565b838052039060015afa15610ddd57600051610db86000610cb9565b610dc18161020b565b610dca8361020b565b14610dd6575090600090565b9160019150565b610d43565b50505050610df06000610cb9565b9060039056fea264697066735822122026eaa5afe824c41e3c871d14cc70209049f891f5c3dfafabfa6792c058934de564736f6c63430008180033