Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 4,743 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Deposit | 17671054 | 113 days ago | IN | 1 ETH | 0.000000213735 | ||||
Transfer Ownersh... | 17669039 | 114 days ago | IN | 0 ETH | 0.000000178304 | ||||
Set Verifying Si... | 17669027 | 114 days ago | IN | 0 ETH | 0.000000184078 | ||||
Set Verifying Si... | 17668328 | 114 days ago | IN | 0 ETH | 0.000000191177 | ||||
Transfer Ownersh... | 17668201 | 114 days ago | IN | 0 ETH | 0.000000166687 | ||||
Set Verifying Si... | 17499834 | 117 days ago | IN | 0 ETH | 0.000000417703 | ||||
Transfer Ownersh... | 17499709 | 117 days ago | IN | 0 ETH | 0.000000384877 | ||||
Deposit | 15734989 | 158 days ago | IN | 5 ETH | 0.000016219418 | ||||
Deposit | 15014437 | 175 days ago | IN | 20 ETH | 0.000002745967 | ||||
Deposit | 13968150 | 199 days ago | IN | 5 ETH | 0.000001547363 | ||||
Deposit | 13755941 | 204 days ago | IN | 5 ETH | 0.000123600527 | ||||
Deposit | 13739371 | 204 days ago | IN | 5 ETH | 0.000001576216 | ||||
Deposit | 13704372 | 205 days ago | IN | 25 ETH | 0.000216610098 | ||||
Deposit | 12888252 | 224 days ago | IN | 15 ETH | 0.000004912205 | ||||
Add Stake | 12287136 | 238 days ago | IN | 1 ETH | 0.000066836374 | ||||
Deposit | 11852523 | 248 days ago | IN | 100 ETH | 0.000098278889 | ||||
Deposit | 11148805 | 264 days ago | IN | 50 ETH | 0.000062841266 | ||||
Deposit | 11113259 | 265 days ago | IN | 50 ETH | 0.000918192532 | ||||
Deposit | 11113029 | 265 days ago | IN | 5 ETH | 0.00105334925 | ||||
Deposit | 11113028 | 265 days ago | IN | 5 ETH | 0.001053456426 | ||||
Deposit | 10562116 | 278 days ago | IN | 10 ETH | 0.000059789192 | ||||
Join Membership | 10501072 | 279 days ago | IN | 0 ETH | 0.000161552745 | ||||
Join Membership | 10500517 | 279 days ago | IN | 0 ETH | 0.00016801968 | ||||
Join Membership | 10500275 | 279 days ago | IN | 0 ETH | 0.00015533479 | ||||
Join Membership | 10499637 | 279 days ago | IN | 0 ETH | 0.000155334788 |
Latest 23 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
17671054 | 113 days ago | 1 ETH | ||||
15734989 | 158 days ago | 5 ETH | ||||
15014437 | 175 days ago | 20 ETH | ||||
13968150 | 199 days ago | 5 ETH | ||||
13755941 | 204 days ago | 5 ETH | ||||
13739371 | 204 days ago | 5 ETH | ||||
13704372 | 205 days ago | 25 ETH | ||||
12888252 | 224 days ago | 15 ETH | ||||
12287136 | 238 days ago | 1 ETH | ||||
11852523 | 248 days ago | 100 ETH | ||||
11148805 | 264 days ago | 50 ETH | ||||
11113259 | 265 days ago | 50 ETH | ||||
11113029 | 265 days ago | 5 ETH | ||||
11113028 | 265 days ago | 5 ETH | ||||
10562116 | 278 days ago | 10 ETH | ||||
10372559 | 282 days ago | 6 ETH | ||||
9906176 | 293 days ago | 5 ETH | ||||
9906174 | 293 days ago | 5 ETH | ||||
9874016 | 294 days ago | 2 ETH | ||||
9598653 | 300 days ago | 0.5 ETH | ||||
9511182 | 302 days ago | 0.5 ETH | ||||
9511149 | 302 days ago | 0.1 ETH | ||||
9509588 | 302 days ago | 0.1 ETH |
Loading...
Loading
Contract Name:
PCMPaymaster
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "../core/BasePaymaster.sol"; import "../core/Helpers.sol"; import "../interfaces/UserOperation.sol"; import "./oracle/IOracle.sol"; import "../interfaces/IEntryPoint.sol"; contract PCMPaymaster is BasePaymaster { using ECDSA for bytes32; using UserOperationLib for UserOperation; struct TokenPaymasterConfig { uint256 priceMarkup; uint256 minEntryPointBalance; uint256 refundPostopCost; uint48 priceMaxAge; } string private signature; address private verifyingSigner; IERC20 public token; uint256 public tokenDecimals; IOracle public tokenOracle; IOracle public nativeAssetOracle; uint256 public cachedPrice; uint256 public PRICE_DENOMINATOR = 1e6; uint256 public PRICE_LOCAL = 1e26; TokenPaymasterConfig public tokenPaymasterConfig; mapping(address => uint256) public membership; event ConfigUpdated(TokenPaymasterConfig tokenPaymasterConfig); event UserOperationValidated( address indexed user, uint256 tokenAmount, uint256 preChargeNative, uint256 cachedPrice ); event UserOperationSponsored( address indexed user, uint256 actualTokenNeeded, uint256 preCharge, uint256 actualTokenPrice ); event PostOpReverted(address indexed user, uint256 preCharge); event Received(address indexed sender, uint256 value); event PaymasterSignatureReverted(address indexed sender,bytes32 hash); event JoinMembership(address indexed sender,uint256 value); constructor( IERC20Metadata _token, IEntryPoint _entryPoint, IOracle _tokenOracle, IOracle _nativeAssetOracle, TokenPaymasterConfig memory _tokenPaymasterConfig, address _owner, string memory _signature ) BasePaymaster(_entryPoint) Ownable(_owner) { token = _token; tokenOracle = _tokenOracle; nativeAssetOracle = _nativeAssetOracle; tokenDecimals = _token.decimals(); signature = _signature; verifyingSigner = _owner; require(_tokenOracle.decimals() == 8,"VP-ERC20 : token oracle decimals must be 8"); require(_nativeAssetOracle.decimals() == 8,"VP-ERC20 : native asset oracle decimals must be 8"); setTokenPaymasterConfig(_tokenPaymasterConfig); transferOwnership(_owner); updatePrice(); } function setSignature(string memory _signature) public onlyOwner { signature = _signature; } function getSignature() public view onlyOwner returns (string memory){ return signature; } function setVerifyingSigner(address _verifyingSigner) public onlyOwner { verifyingSigner = _verifyingSigner; } function getVerifyingSigner() public view onlyOwner returns(address){ return verifyingSigner; } function setPriceLocal(uint256 _priceLocal) public onlyOwner { PRICE_LOCAL = _priceLocal; } function setPriceDenominator(uint256 _priceDenominator) public onlyOwner { PRICE_DENOMINATOR = _priceDenominator; } function updatePrice() private { cachedPrice = fetchPrice(nativeAssetOracle); } function updateToken(IERC20 _token, uint256 _tokenDecimals) external onlyOwner{ token = _token; tokenDecimals = _tokenDecimals; } function updateTokenOracle(IOracle _tokenOracle) external onlyOwner { tokenOracle = _tokenOracle; } function updateNativeAssetOracle(IOracle _nativeAssetOracle) external onlyOwner{ nativeAssetOracle = _nativeAssetOracle; } function setTokenPaymasterConfig(TokenPaymasterConfig memory _tokenPaymasterConfig) public onlyOwner { require( _tokenPaymasterConfig.priceMarkup <= 2 * PRICE_DENOMINATOR, "TPM: price markup too high" ); require( _tokenPaymasterConfig.priceMarkup >= PRICE_DENOMINATOR, "TPM: price markup too low" ); tokenPaymasterConfig = _tokenPaymasterConfig; emit ConfigUpdated(_tokenPaymasterConfig); } function withdrawToken(address _to, uint256 _amount) external onlyOwner { token.transfer(_to, _amount); } function joinMembership(address sender,uint256 amount) public onlyOwner returns(bool){ _jsonMembership(sender,amount); return true; } function _jsonMembership(address sender,uint256 amount) private { membership[sender] = amount; emit JoinMembership(sender,amount); } function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32, uint256 requiredPreFund) internal override returns (bytes memory context, uint256 validationData){ (requiredPreFund); address sender = userOp.getSender(); uint256 maxFeePerGas = userOp.maxFeePerGas; uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; (uint48 validUntil,uint48 validAfter, bytes calldata signatureData) = parsePaymasterAndData(userOp.paymasterAndData); bytes32 signatureHash = getSignatureHash(userOp.sender,userOp.nonce,validUntil,validAfter); bytes32 hash = signatureHash.toEthSignedMessageHash(); if (verifyingSigner != hash.recover(signatureData)) { emit PaymasterSignatureReverted(sender,hash); return ("",_packValidationData(true,validUntil,validAfter)); } uint256 memberAmount = membership[sender]; uint256 tokenAmount = 0; uint256 preChargeNative = requiredPreFund + (tokenPaymasterConfig.refundPostopCost * maxFeePerGas); uint256 cachedPriceWithMarkup = (cachedPrice * PRICE_DENOMINATOR) / tokenPaymasterConfig.priceMarkup; if (memberAmount > 0) { tokenAmount = weiToToken(preChargeNative,cachedPriceWithMarkup); token.transferFrom( sender, address(this), tokenAmount ); membership[sender] += tokenAmount; } else { token.transferFrom( sender, address(this), tokenAmount ); } context = abi.encode( tokenAmount, maxFeePerGas, maxPriorityFeePerGas, sender ); emit UserOperationValidated( sender, tokenAmount, preChargeNative, cachedPrice ); return (context,_packValidationData(false,validUntil,0)); } function _postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) internal override { unchecked { ( uint256 preCharge, uint256 maxFeePerGas, uint256 maxPriorityFeePerGas, address userOpSender ) = abi.decode(context, (uint256, uint256, uint256, address)); if (mode == PostOpMode.postOpReverted) { emit PostOpReverted(userOpSender, preCharge); } updatePrice(); uint256 gasPrice = getGasPrice(maxFeePerGas, maxPriorityFeePerGas); uint256 cachedPriceWithMarkup = (cachedPrice * PRICE_DENOMINATOR) / tokenPaymasterConfig.priceMarkup; uint256 actualChargeNative = actualGasCost + tokenPaymasterConfig.refundPostopCost * gasPrice; uint256 actualTokenNeeded = weiToToken(actualChargeNative, cachedPriceWithMarkup); if (preCharge > actualTokenNeeded) { // token.transferFrom( // address(this), // userOpSender, // preCharge - actualTokenNeeded // ); token.transfer(userOpSender, preCharge - actualTokenNeeded); } else { uint256 memberAmount = membership[userOpSender]; uint256 tokenFeeAmount = 0; if (memberAmount > 0) { tokenFeeAmount = actualTokenNeeded - preCharge; token.transferFrom( userOpSender, address(this), tokenFeeAmount ); membership[userOpSender] += tokenFeeAmount; } else { token.transferFrom( userOpSender, address(this), tokenFeeAmount ); } } emit UserOperationSponsored( userOpSender, actualTokenNeeded, preCharge, cachedPrice ); } } function getGasPrice(uint256 maxFeePerGas, uint256 maxPriorityFeePerGas) internal pure returns (uint256){ if (maxFeePerGas == maxPriorityFeePerGas) { return maxFeePerGas; } return min(maxFeePerGas, maxPriorityFeePerGas); } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } receive() external payable { emit Received(msg.sender, msg.value); } function fetchPrice(IOracle _oracle) internal view returns (uint192 price) { (uint80 roundId, int256 answer,,, uint80 answeredInRound) = _oracle.latestRoundData(); require(answer > 0, "PP-ERC20 : Chainlink price <= 0"); require(answeredInRound >= roundId, "PP-ERC20 : Stale price"); price = uint192(int192(answer)); } function weiToToken(uint256 amount, uint256 price) internal view returns (uint256) { return (amount * price) * tokenDecimals / PRICE_LOCAL; } function parsePaymasterAndData(bytes calldata paymasterAndData) private pure returns(uint48 validUntil,uint48 validAfter, bytes calldata signatureData) { bytes calldata timesData = paymasterAndData[20:84]; (validUntil,validAfter) = abi.decode(timesData,(uint48,uint48)); signatureData = paymasterAndData[84:]; } function getSignatureHash(address sender,uint256 nonce,uint48 validUntil,uint48 validAfter) public view returns(bytes32) { return keccak256( abi.encode(sender,nonce,signature,validUntil,validAfter) ); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; /* solhint-disable avoid-low-level-calls */ /* solhint-disable no-inline-assembly */ /* solhint-disable reason-string */ import "./UserOperation.sol"; import "./IStakeManager.sol"; import "./IAggregator.sol"; import "./INonceManager.sol"; interface IEntryPoint is IStakeManager, INonceManager { /*** * An event emitted after each successful request * @param userOpHash - unique identifier for the request (hash its entire content, except signature). * @param sender - the account that generates this request. * @param paymaster - if non-null, the paymaster that pays for this request. * @param nonce - the nonce value from the request. * @param success - true if the sender transaction succeeded, false if reverted. * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation. * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution). */ event UserOperationEvent( bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed ); /** * account "sender" was deployed. * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow. * @param sender the account that is deployed * @param factory the factory used to deploy this account (in the initCode) * @param paymaster the paymaster used by this UserOp */ event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster); /** * An event emitted if the UserOperation "callData" reverted with non-zero length * @param userOpHash the request unique identifier. * @param sender the sender of this request * @param nonce the nonce used in the request * @param revertReason - the return bytes from the (reverted) call to "callData". */ event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason); /** * an event emitted by handleOps(), before starting the execution loop. * any event emitted before this event, is part of the validation. */ event BeforeExecution(); /** * signature aggregator used by the following UserOperationEvents within this bundle. */ event SignatureAggregatorChanged(address indexed aggregator); /** * a custom revert error of handleOps, to identify the offending op. * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it. * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero) * @param reason - revert reason * The string starts with a unique code "AAmn", where "m" is "1" for factory, "2" for account and "3" for paymaster issues, * so a failure can be attributed to the correct entity. * Should be caught in off-chain handleOps simulation and not happen on-chain. * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts. */ error FailedOp(uint256 opIndex, string reason); /** * error case when a signature aggregator fails to verify the aggregated signature it had created. */ error SignatureValidationFailed(address aggregator); /** * Successful result from simulateValidation. * @param returnInfo gas and time-range returned values * @param senderInfo stake information about the sender * @param factoryInfo stake information about the factory (if any) * @param paymasterInfo stake information about the paymaster (if any) */ error ValidationResult(ReturnInfo returnInfo, StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo); /** * Successful result from simulateValidation, if the account returns a signature aggregator * @param returnInfo gas and time-range returned values * @param senderInfo stake information about the sender * @param factoryInfo stake information about the factory (if any) * @param paymasterInfo stake information about the paymaster (if any) * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator) * bundler MUST use it to verify the signature, or reject the UserOperation */ error ValidationResultWithAggregation( ReturnInfo returnInfo, StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo, AggregatorStakeInfo aggregatorInfo ); /** * return value of getSenderAddress */ error SenderAddressResult(address sender); /** * return value of simulateHandleOp */ error ExecutionResult( uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult ); //UserOps handled, per aggregator struct UserOpsPerAggregator { UserOperation[] userOps; // aggregator address IAggregator aggregator; // aggregated signature bytes signature; } /** * Execute a batch of UserOperation. * no signature aggregator is used. * if any account requires an aggregator (that is, it returned an aggregator when * performing simulateValidation), then handleAggregatedOps() must be used instead. * @param ops the operations to execute * @param beneficiary the address to receive the fees */ function handleOps(UserOperation[] calldata ops, address payable beneficiary) external; /** * Execute a batch of UserOperation with Aggregators * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts) * @param beneficiary the address to receive the fees */ function handleAggregatedOps( UserOpsPerAggregator[] calldata opsPerAggregator, address payable beneficiary ) external; /** * generate a request Id - unique identifier for this request. * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid. */ function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32); /** * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp. * @dev this method always revert. Successful result is ValidationResult error. other errors are failures. * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data. * @param userOp the user operation to validate. */ function simulateValidation(UserOperation calldata userOp) external; /** * gas and return values during simulation * @param preOpGas the gas used for validation (including preValidationGas) * @param prefund the required prefund for this operation * @param sigFailed validateUserOp's (or paymaster's) signature check failed * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range) * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range) * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp) */ struct ReturnInfo { uint256 preOpGas; uint256 prefund; bool sigFailed; uint48 validAfter; uint48 validUntil; bytes paymasterContext; } /** * returned aggregated signature info. * the aggregator returned by the account, and its current stake. */ struct AggregatorStakeInfo { address aggregator; StakeInfo stakeInfo; } /** * Get counterfactual sender address. * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. * this method always revert, and returns the address in SenderAddressResult error * @param initCode the constructor code to be passed into the UserOperation. */ function getSenderAddress(bytes memory initCode) external; /** * simulate full execution of a UserOperation (including both validation and target execution) * this method will always revert with "ExecutionResult". * it performs full validation of the UserOperation, but ignores signature error. * an optional target address is called after the userop succeeds, and its value is returned * (before the entire call is reverted) * Note that in order to collect the the success/failure of the target call, it must be executed * with trace enabled to track the emitted events. * @param op the UserOperation to simulate * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult * are set to the return from that call. * @param targetCallData callData to pass to target address */ function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; interface IOracle { function decimals() external view returns (uint8); function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; /* solhint-disable no-inline-assembly */ import {calldataKeccak} from "../core/Helpers.sol"; /** * User Operation struct * @param sender - The sender account of this request. * @param nonce - Unique value the sender uses to verify it is not a replay. * @param initCode - If set, the account contract will be created by this constructor/ * @param callData - The method call to execute on this account. * @param callGasLimit - The gas limit passed to the callData method call. * @param verificationGasLimit - Gas used for validateUserOp and validatePaymasterUserOp. * @param preVerificationGas - Gas not calculated by the handleOps method, but added to the gas paid. * Covers batch overhead. * @param maxFeePerGas - Same as EIP-1559 gas parameter. * @param maxPriorityFeePerGas - Same as EIP-1559 gas parameter. * @param paymasterAndData - If set, this field holds the paymaster address and paymaster-specific data. * The paymaster will pay for the transaction instead of the sender. * @param signature - Sender-verified signature over the entire request, the EntryPoint address and the chain ID. */ struct UserOperation { address sender; uint256 nonce; bytes initCode; bytes callData; uint256 callGasLimit; uint256 verificationGasLimit; uint256 preVerificationGas; uint256 maxFeePerGas; uint256 maxPriorityFeePerGas; bytes paymasterAndData; bytes signature; } /** * Utility functions helpful when working with UserOperation structs. */ library UserOperationLib { /** * Get sender from user operation data. * @param userOp - The user operation data. */ function getSender( UserOperation calldata userOp ) internal pure returns (address) { address data; //read sender from userOp, which is first userOp member (saves 800 gas...) assembly { data := calldataload(userOp) } return address(uint160(data)); } /** * Relayer/block builder might submit the TX with higher priorityFee, * but the user should not pay above what he signed for. * @param userOp - The user operation data. */ function gasPrice( UserOperation calldata userOp ) internal pure returns (uint256) { unchecked { uint256 maxFeePerGas = userOp.maxFeePerGas; uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; if (maxFeePerGas == maxPriorityFeePerGas) { //legacy mode (for networks that don't support basefee opcode) return maxFeePerGas; } return min(maxFeePerGas, maxPriorityFeePerGas); } } /** * Pack the user operation data into bytes for hashing. * @param userOp - The user operation data. */ function pack( UserOperation calldata userOp ) internal pure returns (bytes memory ret) { address sender = getSender(userOp); uint256 nonce = userOp.nonce; bytes32 hashInitCode = calldataKeccak(userOp.initCode); bytes32 hashCallData = calldataKeccak(userOp.callData); uint256 callGasLimit = userOp.callGasLimit; uint256 verificationGasLimit = userOp.verificationGasLimit; uint256 preVerificationGas = userOp.preVerificationGas; uint256 maxFeePerGas = userOp.maxFeePerGas; uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData); return abi.encode( sender, nonce, hashInitCode, hashCallData, callGasLimit, verificationGasLimit, preVerificationGas, maxFeePerGas, maxPriorityFeePerGas, hashPaymasterAndData ); } /** * Hash the user operation data. * @param userOp - The user operation data. */ function hash( UserOperation calldata userOp ) internal pure returns (bytes32) { return keccak256(pack(userOp)); } /** * The minimum of two numbers. * @param a - First number. * @param b - Second number. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; struct ValidationData { address aggregator; uint48 validAfter; uint48 validUntil; } /** * Extract sigFailed, validAfter, validUntil. * Also convert zero validUntil to type(uint48).max. * @param validationData - The packed validation data. */ function _parseValidationData( uint validationData ) pure returns (ValidationData memory data) { address aggregator = address(uint160(validationData)); uint48 validUntil = uint48(validationData >> 160); if (validUntil == 0) { validUntil = type(uint48).max; } uint48 validAfter = uint48(validationData >> (48 + 160)); return ValidationData(aggregator, validAfter, validUntil); } /** * Intersect account and paymaster ranges. * @param validationData - The packed validation data of the account. * @param paymasterValidationData - The packed validation data of the paymaster. */ function _intersectTimeRange( uint256 validationData, uint256 paymasterValidationData ) pure returns (ValidationData memory) { ValidationData memory accountValidationData = _parseValidationData( validationData ); ValidationData memory pmValidationData = _parseValidationData( paymasterValidationData ); address aggregator = accountValidationData.aggregator; if (aggregator == address(0)) { aggregator = pmValidationData.aggregator; } uint48 validAfter = accountValidationData.validAfter; uint48 validUntil = accountValidationData.validUntil; uint48 pmValidAfter = pmValidationData.validAfter; uint48 pmValidUntil = pmValidationData.validUntil; if (validAfter < pmValidAfter) validAfter = pmValidAfter; if (validUntil > pmValidUntil) validUntil = pmValidUntil; return ValidationData(aggregator, validAfter, validUntil); } /** * Helper to pack the return value for validateUserOp. * @param data - The ValidationData to pack. */ function _packValidationData( ValidationData memory data ) pure returns (uint256) { return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48)); } /** * Helper to pack the return value for validateUserOp, when not using an aggregator. * @param sigFailed - True for signature failure, false for success. * @param validUntil - Last timestamp this UserOperation is valid (or zero for infinite). * @param validAfter - First timestamp this UserOperation is valid. */ function _packValidationData( bool sigFailed, uint48 validUntil, uint48 validAfter ) pure returns (uint256) { return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48)); } /** * keccak function over calldata. * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it. */ function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) { assembly { let mem := mload(0x40) let len := data.length calldatacopy(mem, data.offset, len) ret := keccak256(mem, len) } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; /* solhint-disable reason-string */ import "@openzeppelin/contracts/access/Ownable.sol"; import "../interfaces/IPaymaster.sol"; import "../interfaces/IEntryPoint.sol"; import "./Helpers.sol"; /** * Helper class for creating a paymaster. * provides helper methods for staking. * Validates that the postOp is called only by the entryPoint. */ abstract contract BasePaymaster is IPaymaster, Ownable { IEntryPoint public immutable entryPoint; constructor(IEntryPoint _entryPoint) { entryPoint = _entryPoint; } /// @inheritdoc IPaymaster function validatePaymasterUserOp( UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost ) external override returns (bytes memory context, uint256 validationData) { _requireFromEntryPoint(); return _validatePaymasterUserOp(userOp, userOpHash, maxCost); } /** * Validate a user operation. * @param userOp - The user operation. * @param userOpHash - The hash of the user operation. * @param maxCost - The maximum cost of the user operation. */ function _validatePaymasterUserOp( UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost ) internal virtual returns (bytes memory context, uint256 validationData); /// @inheritdoc IPaymaster function postOp( PostOpMode mode, bytes calldata context, uint256 actualGasCost ) external override { _requireFromEntryPoint(); _postOp(mode, context, actualGasCost); } /** * Post-operation handler. * (verified to be called only through the entryPoint) * @dev If subclass returns a non-empty context from validatePaymasterUserOp, * it must also implement this method. * @param mode - Enum with the following options: * opSucceeded - User operation succeeded. * opReverted - User op reverted. still has to pay for gas. * postOpReverted - User op succeeded, but caused postOp (in mode=opSucceeded) to revert. * Now this is the 2nd call, after user's op was deliberately reverted. * @param context - The context value returned by validatePaymasterUserOp * @param actualGasCost - Actual gas used so far (without this postOp call). */ function _postOp( PostOpMode mode, bytes calldata context, uint256 actualGasCost ) internal virtual { (mode, context, actualGasCost); // unused params // subclass must override this method if validatePaymasterUserOp returns a context revert("must override"); } /** * Add a deposit for this paymaster, used for paying for transaction fees. */ function deposit() public payable { entryPoint.depositTo{value: msg.value}(address(this)); } /** * Withdraw value from the deposit. * @param withdrawAddress - Target to send to. * @param amount - Amount to withdraw. */ function withdrawTo( address payable withdrawAddress, uint256 amount ) public onlyOwner { entryPoint.withdrawTo(withdrawAddress, amount); } /** * Add stake for this paymaster. * This method can also carry eth value to add to the current stake. * @param unstakeDelaySec - The unstake delay for this paymaster. Can only be increased. */ function addStake(uint32 unstakeDelaySec) external payable onlyOwner { entryPoint.addStake{value: msg.value}(unstakeDelaySec); } /** * Return current paymaster's deposit on the entryPoint. */ function getDeposit() public view returns (uint256) { return entryPoint.balanceOf(address(this)); } /** * Unlock the stake, in order to withdraw it. * The paymaster can't serve requests once unlocked, until it calls addStake again */ function unlockStake() external onlyOwner { entryPoint.unlockStake(); } /** * Withdraw the entire paymaster's stake. * stake must be unlocked first (and then wait for the unstakeDelay to be over) * @param withdrawAddress - The address to send withdrawn value. */ function withdrawStake(address payable withdrawAddress) external onlyOwner { entryPoint.withdrawStake(withdrawAddress); } /** * Validate the call is made from a valid entrypoint */ function _requireFromEntryPoint() internal virtual { require(msg.sender == address(entryPoint), "Sender not EntryPoint"); } }
// 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. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.20; import {MessageHashUtils} from "./MessageHashUtils.sol"; import {ShortStrings, ShortString} from "../ShortStrings.sol"; import {IERC5267} from "../../interfaces/IERC5267.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * @custom:oz-upgrades-unsafe-allow state-variable-immutable */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {IERC-5267}. */ function eip712Domain() public view virtual returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _EIP712Name(), _EIP712Version(), block.chainid, address(this), bytes32(0), new uint256[](0) ); } /** * @dev The name parameter for the EIP712 domain. * * NOTE: By default this function reads _name which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Name() internal view returns (string memory) { return _name.toStringWithFallback(_nameFallback); } /** * @dev The version parameter for the EIP712 domain. * * NOTE: By default this function reads _version which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Version() internal view returns (string memory) { return _version.toStringWithFallback(_versionFallback); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; interface INonceManager { /** * Return the next nonce for this sender. * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) * But UserOp with different keys can come with arbitrary order. * * @param sender the account address * @param key the high 192 bit of the nonce * @return nonce a full nonce to pass for next UserOp with this sender. */ function getNonce(address sender, uint192 key) external view returns (uint256 nonce); /** * Manually increment the nonce of the sender. * This method is exposed just for completeness.. * Account does NOT need to call it, neither during validation, nor elsewhere, * as the EntryPoint will update the nonce regardless. * Possible use-case is call it with various keys to "initialize" their nonces to one, so that future * UserOperations will not pay extra for the first transaction with a given key. */ function incrementNonce(uint192 key) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; import "./UserOperation.sol"; /** * Aggregated Signatures validator. */ interface IAggregator { /** * validate aggregated signature. * revert if the aggregated signature does not match the given list of operations. */ function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view; /** * validate signature of a single userOp * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps. * @param userOp the userOperation received from the user. * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps. * (usually empty, unless account and aggregator support some kind of "multisig" */ function validateUserOpSignature(UserOperation calldata userOp) external view returns (bytes memory sigForUserOp); /** * aggregate multiple signatures into a single value. * This method is called off-chain to calculate the signature to pass with handleOps() * bundler MAY use optimized custom code perform this aggregation * @param userOps array of UserOperations to collect the signatures from. * @return aggregatedSignature the aggregated signature */ function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; /** * manage deposits and stakes. * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account) * stake is value locked for at least "unstakeDelay" by the staked entity. */ interface IStakeManager { event Deposited( address indexed account, uint256 totalDeposit ); event Withdrawn( address indexed account, address withdrawAddress, uint256 amount ); /// Emitted when stake or unstake delay are modified event StakeLocked( address indexed account, uint256 totalStaked, uint256 unstakeDelaySec ); /// Emitted once a stake is scheduled for withdrawal event StakeUnlocked( address indexed account, uint256 withdrawTime ); event StakeWithdrawn( address indexed account, address withdrawAddress, uint256 amount ); /** * @param deposit the entity's deposit * @param staked true if this entity is staked. * @param stake actual amount of ether staked for this entity. * @param unstakeDelaySec minimum delay to withdraw the stake. * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps) * and the rest fit into a 2nd cell. * 112 bit allows for 10^15 eth * 48 bit for full timestamp * 32 bit allows 150 years for unstake delay */ struct DepositInfo { uint112 deposit; bool staked; uint112 stake; uint32 unstakeDelaySec; uint48 withdrawTime; } //API struct used by getStakeInfo and simulateValidation struct StakeInfo { uint256 stake; uint256 unstakeDelaySec; } /// @return info - full deposit information of given account function getDepositInfo(address account) external view returns (DepositInfo memory info); /// @return the deposit (for gas payment) of the account function balanceOf(address account) external view returns (uint256); /** * add to the deposit of the given account */ function depositTo(address account) external payable; /** * add to the account's stake - amount and delay * any pending unstake is first cancelled. * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn. */ function addStake(uint32 _unstakeDelaySec) external payable; /** * attempt to unlock the stake. * the value can be withdrawn (using withdrawStake) after the unstake delay. */ function unlockStake() external; /** * withdraw from the (unlocked) stake. * must first call unlockStake and wait for the unstakeDelay to pass * @param withdrawAddress the address to send withdrawn value. */ function withdrawStake(address payable withdrawAddress) external; /** * withdraw from the deposit. * @param withdrawAddress the address to send withdrawn value. * @param withdrawAmount the amount to withdraw. */ function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; import "./UserOperation.sol"; /** * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations. * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction. */ interface IPaymaster { enum PostOpMode { opSucceeded, // user op succeeded opReverted, // user op reverted. still has to pay for gas. postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted. } /** * payment validation: check if paymaster agrees to pay. * Must verify sender is the entryPoint. * Revert to reject this request. * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted) * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns. * @param userOp the user operation * @param userOpHash hash of the user's request data. * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp) * @return context value to send to a postOp * zero length to signify postOp is not required. * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure, * otherwise, an address of an "authorizer" contract. * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite" * <6-byte> validAfter - first timestamp this operation is valid * Note that the validation code cannot use block.timestamp (or block.number) directly. */ function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost) external returns (bytes memory context, uint256 validationData); /** * post-operation handler. * Must verify sender is the entryPoint * @param mode enum with the following options: * opSucceeded - user operation succeeded. * opReverted - user op reverted. still has to pay for gas. * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert. * Now this is the 2nd call, after user's op was deliberately reverted. * @param context - the context value returned by validatePaymasterUserOp * @param actualGasCost - actual gas used so far (without this postOp call). */ function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.20; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol) pragma solidity ^0.8.8; import "./StorageSlot.sol"; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(_FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol) pragma solidity ^0.8.20; import {Strings} from "../Strings.sol"; /** * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. * * The library provides methods for generating a hash of a message that conforms to the * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] * specifications. */ library MessageHashUtils { /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing a bytes32 `messageHash` with * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with * keccak256, although any bytes32 value can be safely used because the final digest will * be re-hashed. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) } } /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing an arbitrary `message` with * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) { return keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message)); } /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x00` (data with intended validator). * * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended * `validator` address. Then hashing the result. * * See {ECDSA-recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked(hex"19_00", validator, data)); } /** * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`). * * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with * `\x19\x01` and hashing the result. It corresponds to the hash signed by the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. * * See {ECDSA-recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, hex"19_01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) digest := keccak256(ptr, 0x42) } } }
// 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-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// 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); } } }
// 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 infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "remappings": [] }
[{"inputs":[{"internalType":"contract IERC20Metadata","name":"_token","type":"address"},{"internalType":"contract IEntryPoint","name":"_entryPoint","type":"address"},{"internalType":"contract IOracle","name":"_tokenOracle","type":"address"},{"internalType":"contract IOracle","name":"_nativeAssetOracle","type":"address"},{"components":[{"internalType":"uint256","name":"priceMarkup","type":"uint256"},{"internalType":"uint256","name":"minEntryPointBalance","type":"uint256"},{"internalType":"uint256","name":"refundPostopCost","type":"uint256"},{"internalType":"uint48","name":"priceMaxAge","type":"uint48"}],"internalType":"struct PCMPaymaster.TokenPaymasterConfig","name":"_tokenPaymasterConfig","type":"tuple"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"string","name":"_signature","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"priceMarkup","type":"uint256"},{"internalType":"uint256","name":"minEntryPointBalance","type":"uint256"},{"internalType":"uint256","name":"refundPostopCost","type":"uint256"},{"internalType":"uint48","name":"priceMaxAge","type":"uint48"}],"indexed":false,"internalType":"struct PCMPaymaster.TokenPaymasterConfig","name":"tokenPaymasterConfig","type":"tuple"}],"name":"ConfigUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"JoinMembership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"PaymasterSignatureReverted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"preCharge","type":"uint256"}],"name":"PostOpReverted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Received","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"actualTokenNeeded","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"preCharge","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"actualTokenPrice","type":"uint256"}],"name":"UserOperationSponsored","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"preChargeNative","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cachedPrice","type":"uint256"}],"name":"UserOperationValidated","type":"event"},{"inputs":[],"name":"PRICE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE_LOCAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"unstakeDelaySec","type":"uint32"}],"name":"addStake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"cachedPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"entryPoint","outputs":[{"internalType":"contract IEntryPoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSignature","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint48","name":"validUntil","type":"uint48"},{"internalType":"uint48","name":"validAfter","type":"uint48"}],"name":"getSignatureHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVerifyingSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"joinMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"membership","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeAssetOracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IPaymaster.PostOpMode","name":"mode","type":"uint8"},{"internalType":"bytes","name":"context","type":"bytes"},{"internalType":"uint256","name":"actualGasCost","type":"uint256"}],"name":"postOp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_priceDenominator","type":"uint256"}],"name":"setPriceDenominator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_priceLocal","type":"uint256"}],"name":"setPriceLocal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_signature","type":"string"}],"name":"setSignature","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"priceMarkup","type":"uint256"},{"internalType":"uint256","name":"minEntryPointBalance","type":"uint256"},{"internalType":"uint256","name":"refundPostopCost","type":"uint256"},{"internalType":"uint48","name":"priceMaxAge","type":"uint48"}],"internalType":"struct PCMPaymaster.TokenPaymasterConfig","name":"_tokenPaymasterConfig","type":"tuple"}],"name":"setTokenPaymasterConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_verifyingSigner","type":"address"}],"name":"setVerifyingSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenOracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPaymasterConfig","outputs":[{"internalType":"uint256","name":"priceMarkup","type":"uint256"},{"internalType":"uint256","name":"minEntryPointBalance","type":"uint256"},{"internalType":"uint256","name":"refundPostopCost","type":"uint256"},{"internalType":"uint48","name":"priceMaxAge","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOracle","name":"_nativeAssetOracle","type":"address"}],"name":"updateNativeAssetOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenDecimals","type":"uint256"}],"name":"updateToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOracle","name":"_tokenOracle","type":"address"}],"name":"updateTokenOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"},{"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"internalType":"uint256","name":"maxCost","type":"uint256"}],"name":"validatePaymasterUserOp","outputs":[{"internalType":"bytes","name":"context","type":"bytes"},{"internalType":"uint256","name":"validationData","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"withdrawAddress","type":"address"}],"name":"withdrawStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"withdrawAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a0604052620f42406008556a52b7d2dcc80cd2e400000060095534801562000026575f80fd5b5060405162004ffb38038062004ffb83398181016040528101906200004c919062000cce565b85825f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000c1575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620000b8919062000daf565b60405180910390fd5b620000d2816200044260201b60201c565b508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508660035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000212573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000238919062000e05565b60ff16600481905550806001908162000252919062001063565b508160025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060088573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002df573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000305919062000e05565b60ff16146200034b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200034290620011cb565b60405180910390fd5b60088473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000397573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620003bd919062000e05565b60ff161462000403576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003fa906200125f565b60405180910390fd5b62000414836200050360201b60201c565b62000425826200063f60201b60201c565b62000435620006d660201b60201c565b5050505050505062001646565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620005136200072a60201b60201c565b6008546002620005249190620012ac565b815f015111156200056c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005639062001344565b60405180910390fd5b600854815f01511015620005b7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005ae90620013b2565b60405180910390fd5b80600a5f820151815f015560208201518160010155604082015181600201556060820151816003015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055509050507f54149e07c75e0520823a5103e2b9ec2a77c09580e2f0a88f5285d6d4a1eb983c816040516200063491906200144f565b60405180910390a150565b6200064f6200072a60201b60201c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620006c2575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620006b9919062000daf565b60405180910390fd5b620006d3816200044260201b60201c565b50565b6200070860065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16620007cc60201b60201c565b77ffffffffffffffffffffffffffffffffffffffffffffffff16600781905550565b6200073a620008f660201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1662000760620008fd60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614620007ca576200078c620008f660201b60201c565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401620007c1919062000daf565b60405180910390fd5b565b5f805f808473ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156200081a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620008409190620014e6565b94505050925092505f82136200088d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200088490620015b8565b60405180910390fd5b8269ffffffffffffffffffff168169ffffffffffffffffffff161015620008eb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620008e29062001626565b60405180910390fd5b819350505050919050565b5f33905090565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620009608262000935565b9050919050565b5f620009738262000954565b9050919050565b620009858162000967565b811462000990575f80fd5b50565b5f81519050620009a3816200097a565b92915050565b5f620009b58262000954565b9050919050565b620009c781620009a9565b8114620009d2575f80fd5b50565b5f81519050620009e581620009bc565b92915050565b5f620009f78262000954565b9050919050565b62000a0981620009eb565b811462000a14575f80fd5b50565b5f8151905062000a2781620009fe565b92915050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b62000a798262000a31565b810181811067ffffffffffffffff8211171562000a9b5762000a9a62000a41565b5b80604052505050565b5f62000aaf62000924565b905062000abd828262000a6e565b919050565b5f819050919050565b62000ad68162000ac2565b811462000ae1575f80fd5b50565b5f8151905062000af48162000acb565b92915050565b5f65ffffffffffff82169050919050565b62000b168162000afa565b811462000b21575f80fd5b50565b5f8151905062000b348162000b0b565b92915050565b5f6080828403121562000b525762000b5162000a2d565b5b62000b5e608062000aa4565b90505f62000b6f8482850162000ae4565b5f83015250602062000b848482850162000ae4565b602083015250604062000b9a8482850162000ae4565b604083015250606062000bb08482850162000b24565b60608301525092915050565b62000bc78162000954565b811462000bd2575f80fd5b50565b5f8151905062000be58162000bbc565b92915050565b5f80fd5b5f80fd5b5f67ffffffffffffffff82111562000c105762000c0f62000a41565b5b62000c1b8262000a31565b9050602081019050919050565b5f5b8381101562000c4757808201518184015260208101905062000c2a565b5f8484015250505050565b5f62000c6862000c628462000bf3565b62000aa4565b90508281526020810184848401111562000c875762000c8662000bef565b5b62000c9484828562000c28565b509392505050565b5f82601f83011262000cb35762000cb262000beb565b5b815162000cc584826020860162000c52565b91505092915050565b5f805f805f805f610140888a03121562000ced5762000cec6200092d565b5b5f62000cfc8a828b0162000993565b975050602062000d0f8a828b01620009d5565b965050604062000d228a828b0162000a17565b955050606062000d358a828b0162000a17565b945050608062000d488a828b0162000b3a565b93505061010062000d5c8a828b0162000bd5565b92505061012088015167ffffffffffffffff81111562000d815762000d8062000931565b5b62000d8f8a828b0162000c9c565b91505092959891949750929550565b62000da98162000954565b82525050565b5f60208201905062000dc45f83018462000d9e565b92915050565b5f60ff82169050919050565b62000de18162000dca565b811462000dec575f80fd5b50565b5f8151905062000dff8162000dd6565b92915050565b5f6020828403121562000e1d5762000e1c6200092d565b5b5f62000e2c8482850162000def565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168062000e8457607f821691505b60208210810362000e9a5762000e9962000e3f565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830262000efe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000ec1565b62000f0a868362000ec1565b95508019841693508086168417925050509392505050565b5f819050919050565b5f62000f4b62000f4562000f3f8462000ac2565b62000f22565b62000ac2565b9050919050565b5f819050919050565b62000f668362000f2b565b62000f7e62000f758262000f52565b84845462000ecd565b825550505050565b5f90565b62000f9462000f86565b62000fa181848462000f5b565b505050565b5b8181101562000fc85762000fbc5f8262000f8a565b60018101905062000fa7565b5050565b601f821115620010175762000fe18162000ea0565b62000fec8462000eb2565b8101602085101562000ffc578190505b620010146200100b8562000eb2565b83018262000fa6565b50505b505050565b5f82821c905092915050565b5f620010395f19846008026200101c565b1980831691505092915050565b5f62001053838362001028565b9150826002028217905092915050565b6200106e8262000e35565b67ffffffffffffffff8111156200108a576200108962000a41565b5b62001096825462000e6c565b620010a382828562000fcc565b5f60209050601f831160018114620010d9575f8415620010c4578287015190505b620010d0858262001046565b8655506200113f565b601f198416620010e98662000ea0565b5f5b828110156200111257848901518255600182019150602085019450602081019050620010eb565b868310156200113257848901516200112e601f89168262001028565b8355505b6001600288020188555050505b505050505050565b5f82825260208201905092915050565b7f56502d4552433230203a20746f6b656e206f7261636c6520646563696d616c735f8201527f206d757374206265203800000000000000000000000000000000000000000000602082015250565b5f620011b3602a8362001147565b9150620011c08262001157565b604082019050919050565b5f6020820190508181035f830152620011e481620011a5565b9050919050565b7f56502d4552433230203a206e6174697665206173736574206f7261636c6520645f8201527f6563696d616c73206d7573742062652038000000000000000000000000000000602082015250565b5f6200124760318362001147565b91506200125482620011eb565b604082019050919050565b5f6020820190508181035f830152620012788162001239565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f620012b88262000ac2565b9150620012c58362000ac2565b9250828202620012d58162000ac2565b91508282048414831517620012ef57620012ee6200127f565b5b5092915050565b7f54504d3a207072696365206d61726b757020746f6f20686967680000000000005f82015250565b5f6200132c601a8362001147565b91506200133982620012f6565b602082019050919050565b5f6020820190508181035f8301526200135d816200131e565b9050919050565b7f54504d3a207072696365206d61726b757020746f6f206c6f77000000000000005f82015250565b5f6200139a60198362001147565b9150620013a78262001364565b602082019050919050565b5f6020820190508181035f830152620013cb816200138c565b9050919050565b620013dd8162000ac2565b82525050565b620013ee8162000afa565b82525050565b608082015f8201516200140a5f850182620013d2565b5060208201516200141f6020850182620013d2565b506040820151620014346040850182620013d2565b506060820151620014496060850182620013e3565b50505050565b5f608082019050620014645f830184620013f4565b92915050565b5f69ffffffffffffffffffff82169050919050565b6200148a816200146a565b811462001495575f80fd5b50565b5f81519050620014a8816200147f565b92915050565b5f819050919050565b620014c281620014ae565b8114620014cd575f80fd5b50565b5f81519050620014e081620014b7565b92915050565b5f805f805f60a086880312156200150257620015016200092d565b5b5f620015118882890162001498565b95505060206200152488828901620014d0565b9450506040620015378882890162000ae4565b93505060606200154a8882890162000ae4565b92505060806200155d8882890162001498565b9150509295509295909350565b7f50502d4552433230203a20436861696e6c696e6b207072696365203c3d2030005f82015250565b5f620015a0601f8362001147565b9150620015ad826200156a565b602082019050919050565b5f6020820190508181035f830152620015d18162001592565b9050919050565b7f50502d4552433230203a205374616c65207072696365000000000000000000005f82015250565b5f6200160e60168362001147565b91506200161b82620015d8565b602082019050919050565b5f6020820190508181035f8301526200163f8162001600565b9050919050565b60805161396b620016905f395f81816107cf0152818161086201528181610d5e01528181610d8a01528181610e0f01528181610e9901528181610f640152611356015261396b5ff3fe6080604052600436106101fc575f3560e01c80638da5cb5b1161010c578063cb721cfd1161009f578063f465c77e1161006e578063f465c77e146106e4578063f5cba98c14610721578063f60fdcb314610749578063fc0c546a14610773578063fd4418531461079d57610251565b8063cb721cfd1461065b578063d0e30db014610688578063efb1ad5d14610692578063f2fde38b146106bc57610251565b8063b0d691fe116100db578063b0d691fe146105c9578063bb9fe6bf146105f3578063c23a5cea14610609578063c399ec881461063157610251565b80638da5cb5b1461052757806396302ab5146105515780639e281a9814610579578063a9a23409146105a157610251565b80634574afbf1161018f578063715018a61161015e578063715018a61461045b578063772ccf5d146104715780637804a2b2146104ad57806383c5c3db146104d55780638a4e3769146104fd57610251565b80634574afbf146103a1578063521e47b9146103dd5780636c1516e1146104075780636c5ec25c1461043157610251565b80632d9c9aa0116101cb5780632d9c9aa0146102e957806333b5ed8f146103255780633b97e8561461034f578063405f9b891461037957610251565b80630396cb6014610255578063205c2878146102715780632782fb22146102995780632bce9e7b146102c157610251565b36610251573373ffffffffffffffffffffffffffffffffffffffff167f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874346040516102479190612192565b60405180910390a2005b5f80fd5b61026f600480360381019061026a91906121f5565b6107c5565b005b34801561027c575f80fd5b50610297600480360381019061029291906122a4565b610858565b005b3480156102a4575f80fd5b506102bf60048036038101906102ba919061241e565b6108ec565b005b3480156102cc575f80fd5b506102e760048036038101906102e291906124b1565b610907565b005b3480156102f4575f80fd5b5061030f600480360381019061030a9190612519565b61095a565b60405161031c9190612571565b60405180910390f35b348015610330575f80fd5b50610339610977565b6040516103469190612192565b60405180910390f35b34801561035a575f80fd5b5061036361097d565b6040516103709190612192565b60405180910390f35b348015610384575f80fd5b5061039f600480360381019061039a919061263e565b610983565b005b3480156103ac575f80fd5b506103c760048036038101906103c29190612669565b610aad565b6040516103d491906126e5565b60405180910390f35b3480156103e8575f80fd5b506103f1610ae8565b6040516103fe919061270d565b60405180910390f35b348015610412575f80fd5b5061041b610b18565b6040516104289190612192565b60405180910390f35b34801561043c575f80fd5b50610445610b1e565b6040516104529190612781565b60405180910390f35b348015610466575f80fd5b5061046f610b43565b005b34801561047c575f80fd5b506104976004803603810190610492919061279a565b610b56565b6040516104a49190612192565b60405180910390f35b3480156104b8575f80fd5b506104d360048036038101906104ce91906127c5565b610b6b565b005b3480156104e0575f80fd5b506104fb60048036038101906104f6919061282b565b610b7d565b005b348015610508575f80fd5b50610511610bc8565b60405161051e91906128d0565b60405180910390f35b348015610532575f80fd5b5061053b610c60565b604051610548919061270d565b60405180910390f35b34801561055c575f80fd5b50610577600480360381019061057291906127c5565b610c87565b005b348015610584575f80fd5b5061059f600480360381019061059a9190612519565b610c99565b005b3480156105ac575f80fd5b506105c760048036038101906105c29190612970565b610d42565b005b3480156105d4575f80fd5b506105dd610d5c565b6040516105ea9190612a01565b60405180910390f35b3480156105fe575f80fd5b50610607610d80565b005b348015610614575f80fd5b5061062f600480360381019061062a9190612a1a565b610e05565b005b34801561063c575f80fd5b50610645610e96565b6040516106529190612192565b60405180910390f35b348015610666575f80fd5b5061066f610f34565b60405161067f9493929190612a54565b60405180910390f35b610690610f62565b005b34801561069d575f80fd5b506106a6610fec565b6040516106b39190612781565b60405180910390f35b3480156106c7575f80fd5b506106e260048036038101906106dd919061279a565b611011565b005b3480156106ef575f80fd5b5061070a60048036038101906107059190612ae4565b611095565b604051610718929190612ba2565b60405180910390f35b34801561072c575f80fd5b506107476004803603810190610742919061279a565b6110b7565b005b348015610754575f80fd5b5061075d611102565b60405161076a9190612192565b60405180910390f35b34801561077e575f80fd5b50610787611108565b6040516107949190612bf0565b60405180910390f35b3480156107a8575f80fd5b506107c360048036038101906107be919061282b565b61112d565b005b6107cd611178565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630396cb6034836040518363ffffffff1660e01b81526004016108279190612c18565b5f604051808303818588803b15801561083e575f80fd5b505af1158015610850573d5f803e3d5ffd5b505050505050565b610860611178565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663205c287883836040518363ffffffff1660e01b81526004016108bb929190612c40565b5f604051808303815f87803b1580156108d2575f80fd5b505af11580156108e4573d5f803e3d5ffd5b505050505050565b6108f4611178565b80600190816109039190612e58565b5050565b61090f611178565b8160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806004819055505050565b5f610963611178565b61096d83836111ff565b6001905092915050565b60095481565b60045481565b61098b611178565b600854600261099a9190612f54565b815f015111156109df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d690612fdf565b60405180910390fd5b600854815f01511015610a27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1e90613047565b60405180910390fd5b80600a5f820151815f015560208201518160010155604082015181600201556060820151816003015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055509050507f54149e07c75e0520823a5103e2b9ec2a77c09580e2f0a88f5285d6d4a1eb983c81604051610aa291906130d6565b60405180910390a150565b5f848460018585604051602001610ac8959493929190613170565b604051602081830303815290604052805190602001209050949350505050565b5f610af1611178565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60085481565b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610b4b611178565b610b545f611293565b565b600e602052805f5260405f205f915090505481565b610b73611178565b8060098190555050565b610b85611178565b8060055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060610bd2611178565b60018054610bdf90612c94565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0b90612c94565b8015610c565780601f10610c2d57610100808354040283529160200191610c56565b820191905f5260205f20905b815481529060010190602001808311610c3957829003601f168201915b5050505050905090565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610c8f611178565b8060088190555050565b610ca1611178565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401610cfd9291906131c8565b6020604051808303815f875af1158015610d19573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d3d9190613219565b505050565b610d4a611354565b610d56848484846113e4565b50505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b610d88611178565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663bb9fe6bf6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610ded575f80fd5b505af1158015610dff573d5f803e3d5ffd5b50505050565b610e0d611178565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c23a5cea826040518263ffffffff1660e01b8152600401610e669190613244565b5f604051808303815f87803b158015610e7d575f80fd5b505af1158015610e8f573d5f803e3d5ffd5b5050505050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ef0919061270d565b602060405180830381865afa158015610f0b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f2f9190613271565b905090565b600a805f015490806001015490806002015490806003015f9054906101000a900465ffffffffffff16905084565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b760faf934306040518363ffffffff1660e01b8152600401610fbc919061270d565b5f604051808303818588803b158015610fd3575f80fd5b505af1158015610fe5573d5f803e3d5ffd5b5050505050565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611019611178565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611089575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611080919061270d565b60405180910390fd5b61109281611293565b50565b60605f6110a0611354565b6110ab8585856117b4565b91509150935093915050565b6110bf611178565b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60075481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611135611178565b8060065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611180611c1e565b73ffffffffffffffffffffffffffffffffffffffff1661119e610c60565b73ffffffffffffffffffffffffffffffffffffffff16146111fd576111c1611c1e565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016111f4919061270d565b60405180910390fd5b565b80600e5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508173ffffffffffffffffffffffffffffffffffffffff167f5d088021104b0f351f0af35c382a7a9ba43e085ee5b3bf092014f9d6711e3c4a826040516112879190612192565b60405180910390a25050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d9906132e6565b60405180910390fd5b565b5f805f8086868101906113f79190613304565b935093509350935060028081111561141257611411613368565b5b88600281111561142557611424613368565b5b03611479578073ffffffffffffffffffffffffffffffffffffffff167f70d0284ddd39eacb3395a2e94c4dc76dfad486bb418b24573ca1c9097501d57e856040516114709190612192565b60405180910390a25b611481611c25565b5f61148c8484611c71565b90505f600a5f015460085460075402816114a9576114a8613395565b5b0490505f82600a6002015402880190505f6114c48284611c94565b9050808811156115725760035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb86838b036040518363ffffffff1660e01b815260040161152c9291906131c8565b6020604051808303815f875af1158015611548573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061156c9190613219565b50611752565b5f600e5f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f808211156116af57898303905060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8830846040518463ffffffff1660e01b815260040161161f939291906133c2565b6020604051808303815f875af115801561163b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061165f9190613219565b5080600e5f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254019250508190555061174f565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8830846040518463ffffffff1660e01b815260040161170d939291906133c2565b6020604051808303815f875af1158015611729573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061174d9190613219565b505b50505b8473ffffffffffffffffffffffffffffffffffffffff167f46caa0511cf037f06f57a0bf273a2ff04229f5b12fb04675234a6cbe2e7f1a89828a60075460405161179e939291906133f7565b60405180910390a2505050505050505050505050565b60605f806117c186611cc3565b90505f8660e0013590505f87610100013590505f80365f6117f18c8061012001906117ec9190613438565b611cd2565b93509350935093505f61181b8d5f01602081019061180f919061279a565b8e602001358787610aad565b90505f61182782611d29565b905061187f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505082611d5c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1660025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461194e578873ffffffffffffffffffffffffffffffffffffffff167f14b9df78b0b00400baf0cf9e46b1c011001f2e40805b92dffdf2de42c9fc20c58260405161191891906126e5565b60405180910390a261192c60018787611d81565b60405180602001604052805f815250909a509a50505050505050505050611c16565b5f600e5f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f808a600a600201546119a29190612f54565b8f6119ad919061349a565b90505f600a5f01546008546007546119c59190612f54565b6119cf91906134cd565b90505f841115611adc576119e38282611c94565b925060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8e30866040518463ffffffff1660e01b8152600401611a43939291906133c2565b6020604051808303815f875af1158015611a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a839190613219565b5082600e5f8f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ad0919061349a565b92505081905550611b7c565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8e30866040518463ffffffff1660e01b8152600401611b3a939291906133c2565b6020604051808303815f875af1158015611b56573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b7a9190613219565b505b828c8c8f604051602001611b9394939291906134fd565b6040516020818303038152906040529e508c73ffffffffffffffffffffffffffffffffffffffff167f5b652ed1f410854ee6edba4774408df1bf2b629d7485df89ed5215462e9e468e8484600754604051611bf0939291906133f7565b60405180910390a28e611c045f8c5f611d81565b9e509e50505050505050505050505050505b935093915050565b5f33905090565b611c4f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611db8565b77ffffffffffffffffffffffffffffffffffffffffffffffff16600781905550565b5f818303611c8157829050611c8e565b611c8b8383611ed9565b90505b92915050565b5f6009546004548385611ca79190612f54565b611cb19190612f54565b611cbb91906134cd565b905092915050565b5f808235905080915050919050565b5f80365f365f8787601490605492611cec93929190613548565b915091508181810190611cff9190613582565b809650819750505087876054908092611d1a93929190613548565b93509350505092959194509250565b5f7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f5281601c52603c5f209050919050565b5f805f611d698585611ef1565b91509150611d7681611f3d565b819250505092915050565b5f60d08265ffffffffffff16901b60a08465ffffffffffff16901b85611da7575f611daa565b60015b60ff16171790509392505050565b5f805f808473ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611e05573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e299190613632565b94505050925092505f8213611e73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6a906136f3565b60405180910390fd5b8269ffffffffffffffffffff168169ffffffffffffffffffff161015611ece576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec59061375b565b60405180910390fd5b819350505050919050565b5f818310611ee75781611ee9565b825b905092915050565b5f806041835103611f2e575f805f602086015192506040860151915060608601515f1a9050611f22878285856120a2565b94509450505050611f36565b5f6002915091505b9250929050565b5f6004811115611f5057611f4f613368565b5b816004811115611f6357611f62613368565b5b031561209f5760016004811115611f7d57611f7c613368565b5b816004811115611f9057611f8f613368565b5b03611fd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc7906137c3565b60405180910390fd5b60026004811115611fe457611fe3613368565b5b816004811115611ff757611ff6613368565b5b03612037576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202e9061382b565b60405180910390fd5b6003600481111561204b5761204a613368565b5b81600481111561205e5761205d613368565b5b0361209e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612095906138b9565b60405180910390fd5b5b50565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0835f1c11156120da575f600391509150612171565b5f6001878787876040515f81526020016040526040516120fd94939291906138f2565b6020604051602081039080840390855afa15801561211d573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612169575f60019250925050612171565b805f92509250505b94509492505050565b5f819050919050565b61218c8161217a565b82525050565b5f6020820190506121a55f830184612183565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f63ffffffff82169050919050565b6121d4816121bc565b81146121de575f80fd5b50565b5f813590506121ef816121cb565b92915050565b5f6020828403121561220a576122096121b4565b5b5f612217848285016121e1565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61224982612220565b9050919050565b6122598161223f565b8114612263575f80fd5b50565b5f8135905061227481612250565b92915050565b6122838161217a565b811461228d575f80fd5b50565b5f8135905061229e8161227a565b92915050565b5f80604083850312156122ba576122b96121b4565b5b5f6122c785828601612266565b92505060206122d885828601612290565b9150509250929050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612330826122ea565b810181811067ffffffffffffffff8211171561234f5761234e6122fa565b5b80604052505050565b5f6123616121ab565b905061236d8282612327565b919050565b5f67ffffffffffffffff82111561238c5761238b6122fa565b5b612395826122ea565b9050602081019050919050565b828183375f83830152505050565b5f6123c26123bd84612372565b612358565b9050828152602081018484840111156123de576123dd6122e6565b5b6123e98482856123a2565b509392505050565b5f82601f830112612405576124046122e2565b5b81356124158482602086016123b0565b91505092915050565b5f60208284031215612433576124326121b4565b5b5f82013567ffffffffffffffff8111156124505761244f6121b8565b5b61245c848285016123f1565b91505092915050565b5f61246f82612220565b9050919050565b5f61248082612465565b9050919050565b61249081612476565b811461249a575f80fd5b50565b5f813590506124ab81612487565b92915050565b5f80604083850312156124c7576124c66121b4565b5b5f6124d48582860161249d565b92505060206124e585828601612290565b9150509250929050565b6124f881612465565b8114612502575f80fd5b50565b5f81359050612513816124ef565b92915050565b5f806040838503121561252f5761252e6121b4565b5b5f61253c85828601612505565b925050602061254d85828601612290565b9150509250929050565b5f8115159050919050565b61256b81612557565b82525050565b5f6020820190506125845f830184612562565b92915050565b5f80fd5b5f65ffffffffffff82169050919050565b6125a88161258e565b81146125b2575f80fd5b50565b5f813590506125c38161259f565b92915050565b5f608082840312156125de576125dd61258a565b5b6125e86080612358565b90505f6125f784828501612290565b5f83015250602061260a84828501612290565b602083015250604061261e84828501612290565b6040830152506060612632848285016125b5565b60608301525092915050565b5f60808284031215612653576126526121b4565b5b5f612660848285016125c9565b91505092915050565b5f805f8060808587031215612681576126806121b4565b5b5f61268e87828801612505565b945050602061269f87828801612290565b93505060406126b0878288016125b5565b92505060606126c1878288016125b5565b91505092959194509250565b5f819050919050565b6126df816126cd565b82525050565b5f6020820190506126f85f8301846126d6565b92915050565b61270781612465565b82525050565b5f6020820190506127205f8301846126fe565b92915050565b5f819050919050565b5f61274961274461273f84612220565b612726565b612220565b9050919050565b5f61275a8261272f565b9050919050565b5f61276b82612750565b9050919050565b61277b81612761565b82525050565b5f6020820190506127945f830184612772565b92915050565b5f602082840312156127af576127ae6121b4565b5b5f6127bc84828501612505565b91505092915050565b5f602082840312156127da576127d96121b4565b5b5f6127e784828501612290565b91505092915050565b5f6127fa82612465565b9050919050565b61280a816127f0565b8114612814575f80fd5b50565b5f8135905061282581612801565b92915050565b5f602082840312156128405761283f6121b4565b5b5f61284d84828501612817565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561288d578082015181840152602081019050612872565b5f8484015250505050565b5f6128a282612856565b6128ac8185612860565b93506128bc818560208601612870565b6128c5816122ea565b840191505092915050565b5f6020820190508181035f8301526128e88184612898565b905092915050565b600381106128fc575f80fd5b50565b5f8135905061290d816128f0565b92915050565b5f80fd5b5f80fd5b5f8083601f8401126129305761292f6122e2565b5b8235905067ffffffffffffffff81111561294d5761294c612913565b5b60208301915083600182028301111561296957612968612917565b5b9250929050565b5f805f8060608587031215612988576129876121b4565b5b5f612995878288016128ff565b945050602085013567ffffffffffffffff8111156129b6576129b56121b8565b5b6129c28782880161291b565b935093505060406129d587828801612290565b91505092959194509250565b5f6129eb82612750565b9050919050565b6129fb816129e1565b82525050565b5f602082019050612a145f8301846129f2565b92915050565b5f60208284031215612a2f57612a2e6121b4565b5b5f612a3c84828501612266565b91505092915050565b612a4e8161258e565b82525050565b5f608082019050612a675f830187612183565b612a746020830186612183565b612a816040830185612183565b612a8e6060830184612a45565b95945050505050565b5f80fd5b5f6101608284031215612ab157612ab0612a97565b5b81905092915050565b612ac3816126cd565b8114612acd575f80fd5b50565b5f81359050612ade81612aba565b92915050565b5f805f60608486031215612afb57612afa6121b4565b5b5f84013567ffffffffffffffff811115612b1857612b176121b8565b5b612b2486828701612a9b565b9350506020612b3586828701612ad0565b9250506040612b4686828701612290565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b5f612b7482612b50565b612b7e8185612b5a565b9350612b8e818560208601612870565b612b97816122ea565b840191505092915050565b5f6040820190508181035f830152612bba8185612b6a565b9050612bc96020830184612183565b9392505050565b5f612bda82612750565b9050919050565b612bea81612bd0565b82525050565b5f602082019050612c035f830184612be1565b92915050565b612c12816121bc565b82525050565b5f602082019050612c2b5f830184612c09565b92915050565b612c3a8161223f565b82525050565b5f604082019050612c535f830185612c31565b612c606020830184612183565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612cab57607f821691505b602082108103612cbe57612cbd612c67565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612d207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612ce5565b612d2a8683612ce5565b95508019841693508086168417925050509392505050565b5f612d5c612d57612d528461217a565b612726565b61217a565b9050919050565b5f819050919050565b612d7583612d42565b612d89612d8182612d63565b848454612cf1565b825550505050565b5f90565b612d9d612d91565b612da8818484612d6c565b505050565b5b81811015612dcb57612dc05f82612d95565b600181019050612dae565b5050565b601f821115612e1057612de181612cc4565b612dea84612cd6565b81016020851015612df9578190505b612e0d612e0585612cd6565b830182612dad565b50505b505050565b5f82821c905092915050565b5f612e305f1984600802612e15565b1980831691505092915050565b5f612e488383612e21565b9150826002028217905092915050565b612e6182612856565b67ffffffffffffffff811115612e7a57612e796122fa565b5b612e848254612c94565b612e8f828285612dcf565b5f60209050601f831160018114612ec0575f8415612eae578287015190505b612eb88582612e3d565b865550612f1f565b601f198416612ece86612cc4565b5f5b82811015612ef557848901518255600182019150602085019450602081019050612ed0565b86831015612f125784890151612f0e601f891682612e21565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612f5e8261217a565b9150612f698361217a565b9250828202612f778161217a565b91508282048414831517612f8e57612f8d612f27565b5b5092915050565b7f54504d3a207072696365206d61726b757020746f6f20686967680000000000005f82015250565b5f612fc9601a83612860565b9150612fd482612f95565b602082019050919050565b5f6020820190508181035f830152612ff681612fbd565b9050919050565b7f54504d3a207072696365206d61726b757020746f6f206c6f77000000000000005f82015250565b5f613031601983612860565b915061303c82612ffd565b602082019050919050565b5f6020820190508181035f83015261305e81613025565b9050919050565b61306e8161217a565b82525050565b61307d8161258e565b82525050565b608082015f8201516130975f850182613065565b5060208201516130aa6020850182613065565b5060408201516130bd6040850182613065565b5060608201516130d06060850182613074565b50505050565b5f6080820190506130e95f830184613083565b92915050565b5f81546130fb81612c94565b6131058186612860565b9450600182165f811461311f576001811461313557613167565b60ff198316865281151560200286019350613167565b61313e85612cc4565b5f5b8381101561315f57815481890152600182019150602081019050613140565b808801955050505b50505092915050565b5f60a0820190506131835f8301886126fe565b6131906020830187612183565b81810360408301526131a281866130ef565b90506131b16060830185612a45565b6131be6080830184612a45565b9695505050505050565b5f6040820190506131db5f8301856126fe565b6131e86020830184612183565b9392505050565b6131f881612557565b8114613202575f80fd5b50565b5f81519050613213816131ef565b92915050565b5f6020828403121561322e5761322d6121b4565b5b5f61323b84828501613205565b91505092915050565b5f6020820190506132575f830184612c31565b92915050565b5f8151905061326b8161227a565b92915050565b5f60208284031215613286576132856121b4565b5b5f6132938482850161325d565b91505092915050565b7f53656e646572206e6f7420456e747279506f696e7400000000000000000000005f82015250565b5f6132d0601583612860565b91506132db8261329c565b602082019050919050565b5f6020820190508181035f8301526132fd816132c4565b9050919050565b5f805f806080858703121561331c5761331b6121b4565b5b5f61332987828801612290565b945050602061333a87828801612290565b935050604061334b87828801612290565b925050606061335c87828801612266565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6060820190506133d55f8301866126fe565b6133e260208301856126fe565b6133ef6040830184612183565b949350505050565b5f60608201905061340a5f830186612183565b6134176020830185612183565b6134246040830184612183565b949350505050565b5f80fd5b5f80fd5b5f80fd5b5f80833560016020038436030381126134545761345361342c565b5b80840192508235915067ffffffffffffffff82111561347657613475613430565b5b60208301925060018202360383131561349257613491613434565b5b509250929050565b5f6134a48261217a565b91506134af8361217a565b92508282019050808211156134c7576134c6612f27565b5b92915050565b5f6134d78261217a565b91506134e28361217a565b9250826134f2576134f1613395565b5b828204905092915050565b5f6080820190506135105f830187612183565b61351d6020830186612183565b61352a6040830185612183565b61353760608301846126fe565b95945050505050565b5f80fd5b5f80fd5b5f808585111561355b5761355a613540565b5b8386111561356c5761356b613544565b5b6001850283019150848603905094509492505050565b5f8060408385031215613598576135976121b4565b5b5f6135a5858286016125b5565b92505060206135b6858286016125b5565b9150509250929050565b5f69ffffffffffffffffffff82169050919050565b6135de816135c0565b81146135e8575f80fd5b50565b5f815190506135f9816135d5565b92915050565b5f819050919050565b613611816135ff565b811461361b575f80fd5b50565b5f8151905061362c81613608565b92915050565b5f805f805f60a0868803121561364b5761364a6121b4565b5b5f613658888289016135eb565b95505060206136698882890161361e565b945050604061367a8882890161325d565b935050606061368b8882890161325d565b925050608061369c888289016135eb565b9150509295509295909350565b7f50502d4552433230203a20436861696e6c696e6b207072696365203c3d2030005f82015250565b5f6136dd601f83612860565b91506136e8826136a9565b602082019050919050565b5f6020820190508181035f83015261370a816136d1565b9050919050565b7f50502d4552433230203a205374616c65207072696365000000000000000000005f82015250565b5f613745601683612860565b915061375082613711565b602082019050919050565b5f6020820190508181035f83015261377281613739565b9050919050565b7f45434453413a20696e76616c6964207369676e617475726500000000000000005f82015250565b5f6137ad601883612860565b91506137b882613779565b602082019050919050565b5f6020820190508181035f8301526137da816137a1565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e677468005f82015250565b5f613815601f83612860565b9150613820826137e1565b602082019050919050565b5f6020820190508181035f83015261384281613809565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c5f8201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b5f6138a3602283612860565b91506138ae82613849565b604082019050919050565b5f6020820190508181035f8301526138d081613897565b9050919050565b5f60ff82169050919050565b6138ec816138d7565b82525050565b5f6080820190506139055f8301876126d6565b61391260208301866138e3565b61391f60408301856126d6565b61392c60608301846126d6565b9594505050505056fea264697066735822122058ccc6f71b1a510115f9dc3c96fc21547e278904a70cf3b62c2a4d23d2f792f464736f6c634300081600330000000000000000000000006926fbff41d234afe0ad2f1c73558afa83d8d8ae0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d2789000000000000000000000000bfaff33db44f752f39ecf99fc153b7e602c8f798000000000000000000000000bfaff33db44f752f39ecf99fc153b7e602c8f79800000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000009c40000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000036a9ac722158d347738f703db8c40a245c01258e000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000063633373831390000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101fc575f3560e01c80638da5cb5b1161010c578063cb721cfd1161009f578063f465c77e1161006e578063f465c77e146106e4578063f5cba98c14610721578063f60fdcb314610749578063fc0c546a14610773578063fd4418531461079d57610251565b8063cb721cfd1461065b578063d0e30db014610688578063efb1ad5d14610692578063f2fde38b146106bc57610251565b8063b0d691fe116100db578063b0d691fe146105c9578063bb9fe6bf146105f3578063c23a5cea14610609578063c399ec881461063157610251565b80638da5cb5b1461052757806396302ab5146105515780639e281a9814610579578063a9a23409146105a157610251565b80634574afbf1161018f578063715018a61161015e578063715018a61461045b578063772ccf5d146104715780637804a2b2146104ad57806383c5c3db146104d55780638a4e3769146104fd57610251565b80634574afbf146103a1578063521e47b9146103dd5780636c1516e1146104075780636c5ec25c1461043157610251565b80632d9c9aa0116101cb5780632d9c9aa0146102e957806333b5ed8f146103255780633b97e8561461034f578063405f9b891461037957610251565b80630396cb6014610255578063205c2878146102715780632782fb22146102995780632bce9e7b146102c157610251565b36610251573373ffffffffffffffffffffffffffffffffffffffff167f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874346040516102479190612192565b60405180910390a2005b5f80fd5b61026f600480360381019061026a91906121f5565b6107c5565b005b34801561027c575f80fd5b50610297600480360381019061029291906122a4565b610858565b005b3480156102a4575f80fd5b506102bf60048036038101906102ba919061241e565b6108ec565b005b3480156102cc575f80fd5b506102e760048036038101906102e291906124b1565b610907565b005b3480156102f4575f80fd5b5061030f600480360381019061030a9190612519565b61095a565b60405161031c9190612571565b60405180910390f35b348015610330575f80fd5b50610339610977565b6040516103469190612192565b60405180910390f35b34801561035a575f80fd5b5061036361097d565b6040516103709190612192565b60405180910390f35b348015610384575f80fd5b5061039f600480360381019061039a919061263e565b610983565b005b3480156103ac575f80fd5b506103c760048036038101906103c29190612669565b610aad565b6040516103d491906126e5565b60405180910390f35b3480156103e8575f80fd5b506103f1610ae8565b6040516103fe919061270d565b60405180910390f35b348015610412575f80fd5b5061041b610b18565b6040516104289190612192565b60405180910390f35b34801561043c575f80fd5b50610445610b1e565b6040516104529190612781565b60405180910390f35b348015610466575f80fd5b5061046f610b43565b005b34801561047c575f80fd5b506104976004803603810190610492919061279a565b610b56565b6040516104a49190612192565b60405180910390f35b3480156104b8575f80fd5b506104d360048036038101906104ce91906127c5565b610b6b565b005b3480156104e0575f80fd5b506104fb60048036038101906104f6919061282b565b610b7d565b005b348015610508575f80fd5b50610511610bc8565b60405161051e91906128d0565b60405180910390f35b348015610532575f80fd5b5061053b610c60565b604051610548919061270d565b60405180910390f35b34801561055c575f80fd5b50610577600480360381019061057291906127c5565b610c87565b005b348015610584575f80fd5b5061059f600480360381019061059a9190612519565b610c99565b005b3480156105ac575f80fd5b506105c760048036038101906105c29190612970565b610d42565b005b3480156105d4575f80fd5b506105dd610d5c565b6040516105ea9190612a01565b60405180910390f35b3480156105fe575f80fd5b50610607610d80565b005b348015610614575f80fd5b5061062f600480360381019061062a9190612a1a565b610e05565b005b34801561063c575f80fd5b50610645610e96565b6040516106529190612192565b60405180910390f35b348015610666575f80fd5b5061066f610f34565b60405161067f9493929190612a54565b60405180910390f35b610690610f62565b005b34801561069d575f80fd5b506106a6610fec565b6040516106b39190612781565b60405180910390f35b3480156106c7575f80fd5b506106e260048036038101906106dd919061279a565b611011565b005b3480156106ef575f80fd5b5061070a60048036038101906107059190612ae4565b611095565b604051610718929190612ba2565b60405180910390f35b34801561072c575f80fd5b506107476004803603810190610742919061279a565b6110b7565b005b348015610754575f80fd5b5061075d611102565b60405161076a9190612192565b60405180910390f35b34801561077e575f80fd5b50610787611108565b6040516107949190612bf0565b60405180910390f35b3480156107a8575f80fd5b506107c360048036038101906107be919061282b565b61112d565b005b6107cd611178565b7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278973ffffffffffffffffffffffffffffffffffffffff16630396cb6034836040518363ffffffff1660e01b81526004016108279190612c18565b5f604051808303818588803b15801561083e575f80fd5b505af1158015610850573d5f803e3d5ffd5b505050505050565b610860611178565b7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278973ffffffffffffffffffffffffffffffffffffffff1663205c287883836040518363ffffffff1660e01b81526004016108bb929190612c40565b5f604051808303815f87803b1580156108d2575f80fd5b505af11580156108e4573d5f803e3d5ffd5b505050505050565b6108f4611178565b80600190816109039190612e58565b5050565b61090f611178565b8160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806004819055505050565b5f610963611178565b61096d83836111ff565b6001905092915050565b60095481565b60045481565b61098b611178565b600854600261099a9190612f54565b815f015111156109df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d690612fdf565b60405180910390fd5b600854815f01511015610a27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1e90613047565b60405180910390fd5b80600a5f820151815f015560208201518160010155604082015181600201556060820151816003015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055509050507f54149e07c75e0520823a5103e2b9ec2a77c09580e2f0a88f5285d6d4a1eb983c81604051610aa291906130d6565b60405180910390a150565b5f848460018585604051602001610ac8959493929190613170565b604051602081830303815290604052805190602001209050949350505050565b5f610af1611178565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60085481565b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610b4b611178565b610b545f611293565b565b600e602052805f5260405f205f915090505481565b610b73611178565b8060098190555050565b610b85611178565b8060055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060610bd2611178565b60018054610bdf90612c94565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0b90612c94565b8015610c565780601f10610c2d57610100808354040283529160200191610c56565b820191905f5260205f20905b815481529060010190602001808311610c3957829003601f168201915b5050505050905090565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610c8f611178565b8060088190555050565b610ca1611178565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401610cfd9291906131c8565b6020604051808303815f875af1158015610d19573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d3d9190613219565b505050565b610d4a611354565b610d56848484846113e4565b50505050565b7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278981565b610d88611178565b7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278973ffffffffffffffffffffffffffffffffffffffff1663bb9fe6bf6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610ded575f80fd5b505af1158015610dff573d5f803e3d5ffd5b50505050565b610e0d611178565b7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278973ffffffffffffffffffffffffffffffffffffffff1663c23a5cea826040518263ffffffff1660e01b8152600401610e669190613244565b5f604051808303815f87803b158015610e7d575f80fd5b505af1158015610e8f573d5f803e3d5ffd5b5050505050565b5f7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278973ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ef0919061270d565b602060405180830381865afa158015610f0b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f2f9190613271565b905090565b600a805f015490806001015490806002015490806003015f9054906101000a900465ffffffffffff16905084565b7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278973ffffffffffffffffffffffffffffffffffffffff1663b760faf934306040518363ffffffff1660e01b8152600401610fbc919061270d565b5f604051808303818588803b158015610fd3575f80fd5b505af1158015610fe5573d5f803e3d5ffd5b5050505050565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611019611178565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611089575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611080919061270d565b60405180910390fd5b61109281611293565b50565b60605f6110a0611354565b6110ab8585856117b4565b91509150935093915050565b6110bf611178565b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60075481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611135611178565b8060065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611180611c1e565b73ffffffffffffffffffffffffffffffffffffffff1661119e610c60565b73ffffffffffffffffffffffffffffffffffffffff16146111fd576111c1611c1e565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016111f4919061270d565b60405180910390fd5b565b80600e5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508173ffffffffffffffffffffffffffffffffffffffff167f5d088021104b0f351f0af35c382a7a9ba43e085ee5b3bf092014f9d6711e3c4a826040516112879190612192565b60405180910390a25050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d278973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d9906132e6565b60405180910390fd5b565b5f805f8086868101906113f79190613304565b935093509350935060028081111561141257611411613368565b5b88600281111561142557611424613368565b5b03611479578073ffffffffffffffffffffffffffffffffffffffff167f70d0284ddd39eacb3395a2e94c4dc76dfad486bb418b24573ca1c9097501d57e856040516114709190612192565b60405180910390a25b611481611c25565b5f61148c8484611c71565b90505f600a5f015460085460075402816114a9576114a8613395565b5b0490505f82600a6002015402880190505f6114c48284611c94565b9050808811156115725760035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb86838b036040518363ffffffff1660e01b815260040161152c9291906131c8565b6020604051808303815f875af1158015611548573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061156c9190613219565b50611752565b5f600e5f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f808211156116af57898303905060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8830846040518463ffffffff1660e01b815260040161161f939291906133c2565b6020604051808303815f875af115801561163b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061165f9190613219565b5080600e5f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254019250508190555061174f565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8830846040518463ffffffff1660e01b815260040161170d939291906133c2565b6020604051808303815f875af1158015611729573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061174d9190613219565b505b50505b8473ffffffffffffffffffffffffffffffffffffffff167f46caa0511cf037f06f57a0bf273a2ff04229f5b12fb04675234a6cbe2e7f1a89828a60075460405161179e939291906133f7565b60405180910390a2505050505050505050505050565b60605f806117c186611cc3565b90505f8660e0013590505f87610100013590505f80365f6117f18c8061012001906117ec9190613438565b611cd2565b93509350935093505f61181b8d5f01602081019061180f919061279a565b8e602001358787610aad565b90505f61182782611d29565b905061187f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505082611d5c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1660025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461194e578873ffffffffffffffffffffffffffffffffffffffff167f14b9df78b0b00400baf0cf9e46b1c011001f2e40805b92dffdf2de42c9fc20c58260405161191891906126e5565b60405180910390a261192c60018787611d81565b60405180602001604052805f815250909a509a50505050505050505050611c16565b5f600e5f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f808a600a600201546119a29190612f54565b8f6119ad919061349a565b90505f600a5f01546008546007546119c59190612f54565b6119cf91906134cd565b90505f841115611adc576119e38282611c94565b925060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8e30866040518463ffffffff1660e01b8152600401611a43939291906133c2565b6020604051808303815f875af1158015611a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a839190613219565b5082600e5f8f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ad0919061349a565b92505081905550611b7c565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8e30866040518463ffffffff1660e01b8152600401611b3a939291906133c2565b6020604051808303815f875af1158015611b56573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b7a9190613219565b505b828c8c8f604051602001611b9394939291906134fd565b6040516020818303038152906040529e508c73ffffffffffffffffffffffffffffffffffffffff167f5b652ed1f410854ee6edba4774408df1bf2b629d7485df89ed5215462e9e468e8484600754604051611bf0939291906133f7565b60405180910390a28e611c045f8c5f611d81565b9e509e50505050505050505050505050505b935093915050565b5f33905090565b611c4f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611db8565b77ffffffffffffffffffffffffffffffffffffffffffffffff16600781905550565b5f818303611c8157829050611c8e565b611c8b8383611ed9565b90505b92915050565b5f6009546004548385611ca79190612f54565b611cb19190612f54565b611cbb91906134cd565b905092915050565b5f808235905080915050919050565b5f80365f365f8787601490605492611cec93929190613548565b915091508181810190611cff9190613582565b809650819750505087876054908092611d1a93929190613548565b93509350505092959194509250565b5f7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f5281601c52603c5f209050919050565b5f805f611d698585611ef1565b91509150611d7681611f3d565b819250505092915050565b5f60d08265ffffffffffff16901b60a08465ffffffffffff16901b85611da7575f611daa565b60015b60ff16171790509392505050565b5f805f808473ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611e05573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e299190613632565b94505050925092505f8213611e73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6a906136f3565b60405180910390fd5b8269ffffffffffffffffffff168169ffffffffffffffffffff161015611ece576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec59061375b565b60405180910390fd5b819350505050919050565b5f818310611ee75781611ee9565b825b905092915050565b5f806041835103611f2e575f805f602086015192506040860151915060608601515f1a9050611f22878285856120a2565b94509450505050611f36565b5f6002915091505b9250929050565b5f6004811115611f5057611f4f613368565b5b816004811115611f6357611f62613368565b5b031561209f5760016004811115611f7d57611f7c613368565b5b816004811115611f9057611f8f613368565b5b03611fd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc7906137c3565b60405180910390fd5b60026004811115611fe457611fe3613368565b5b816004811115611ff757611ff6613368565b5b03612037576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202e9061382b565b60405180910390fd5b6003600481111561204b5761204a613368565b5b81600481111561205e5761205d613368565b5b0361209e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612095906138b9565b60405180910390fd5b5b50565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0835f1c11156120da575f600391509150612171565b5f6001878787876040515f81526020016040526040516120fd94939291906138f2565b6020604051602081039080840390855afa15801561211d573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612169575f60019250925050612171565b805f92509250505b94509492505050565b5f819050919050565b61218c8161217a565b82525050565b5f6020820190506121a55f830184612183565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f63ffffffff82169050919050565b6121d4816121bc565b81146121de575f80fd5b50565b5f813590506121ef816121cb565b92915050565b5f6020828403121561220a576122096121b4565b5b5f612217848285016121e1565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61224982612220565b9050919050565b6122598161223f565b8114612263575f80fd5b50565b5f8135905061227481612250565b92915050565b6122838161217a565b811461228d575f80fd5b50565b5f8135905061229e8161227a565b92915050565b5f80604083850312156122ba576122b96121b4565b5b5f6122c785828601612266565b92505060206122d885828601612290565b9150509250929050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612330826122ea565b810181811067ffffffffffffffff8211171561234f5761234e6122fa565b5b80604052505050565b5f6123616121ab565b905061236d8282612327565b919050565b5f67ffffffffffffffff82111561238c5761238b6122fa565b5b612395826122ea565b9050602081019050919050565b828183375f83830152505050565b5f6123c26123bd84612372565b612358565b9050828152602081018484840111156123de576123dd6122e6565b5b6123e98482856123a2565b509392505050565b5f82601f830112612405576124046122e2565b5b81356124158482602086016123b0565b91505092915050565b5f60208284031215612433576124326121b4565b5b5f82013567ffffffffffffffff8111156124505761244f6121b8565b5b61245c848285016123f1565b91505092915050565b5f61246f82612220565b9050919050565b5f61248082612465565b9050919050565b61249081612476565b811461249a575f80fd5b50565b5f813590506124ab81612487565b92915050565b5f80604083850312156124c7576124c66121b4565b5b5f6124d48582860161249d565b92505060206124e585828601612290565b9150509250929050565b6124f881612465565b8114612502575f80fd5b50565b5f81359050612513816124ef565b92915050565b5f806040838503121561252f5761252e6121b4565b5b5f61253c85828601612505565b925050602061254d85828601612290565b9150509250929050565b5f8115159050919050565b61256b81612557565b82525050565b5f6020820190506125845f830184612562565b92915050565b5f80fd5b5f65ffffffffffff82169050919050565b6125a88161258e565b81146125b2575f80fd5b50565b5f813590506125c38161259f565b92915050565b5f608082840312156125de576125dd61258a565b5b6125e86080612358565b90505f6125f784828501612290565b5f83015250602061260a84828501612290565b602083015250604061261e84828501612290565b6040830152506060612632848285016125b5565b60608301525092915050565b5f60808284031215612653576126526121b4565b5b5f612660848285016125c9565b91505092915050565b5f805f8060808587031215612681576126806121b4565b5b5f61268e87828801612505565b945050602061269f87828801612290565b93505060406126b0878288016125b5565b92505060606126c1878288016125b5565b91505092959194509250565b5f819050919050565b6126df816126cd565b82525050565b5f6020820190506126f85f8301846126d6565b92915050565b61270781612465565b82525050565b5f6020820190506127205f8301846126fe565b92915050565b5f819050919050565b5f61274961274461273f84612220565b612726565b612220565b9050919050565b5f61275a8261272f565b9050919050565b5f61276b82612750565b9050919050565b61277b81612761565b82525050565b5f6020820190506127945f830184612772565b92915050565b5f602082840312156127af576127ae6121b4565b5b5f6127bc84828501612505565b91505092915050565b5f602082840312156127da576127d96121b4565b5b5f6127e784828501612290565b91505092915050565b5f6127fa82612465565b9050919050565b61280a816127f0565b8114612814575f80fd5b50565b5f8135905061282581612801565b92915050565b5f602082840312156128405761283f6121b4565b5b5f61284d84828501612817565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561288d578082015181840152602081019050612872565b5f8484015250505050565b5f6128a282612856565b6128ac8185612860565b93506128bc818560208601612870565b6128c5816122ea565b840191505092915050565b5f6020820190508181035f8301526128e88184612898565b905092915050565b600381106128fc575f80fd5b50565b5f8135905061290d816128f0565b92915050565b5f80fd5b5f80fd5b5f8083601f8401126129305761292f6122e2565b5b8235905067ffffffffffffffff81111561294d5761294c612913565b5b60208301915083600182028301111561296957612968612917565b5b9250929050565b5f805f8060608587031215612988576129876121b4565b5b5f612995878288016128ff565b945050602085013567ffffffffffffffff8111156129b6576129b56121b8565b5b6129c28782880161291b565b935093505060406129d587828801612290565b91505092959194509250565b5f6129eb82612750565b9050919050565b6129fb816129e1565b82525050565b5f602082019050612a145f8301846129f2565b92915050565b5f60208284031215612a2f57612a2e6121b4565b5b5f612a3c84828501612266565b91505092915050565b612a4e8161258e565b82525050565b5f608082019050612a675f830187612183565b612a746020830186612183565b612a816040830185612183565b612a8e6060830184612a45565b95945050505050565b5f80fd5b5f6101608284031215612ab157612ab0612a97565b5b81905092915050565b612ac3816126cd565b8114612acd575f80fd5b50565b5f81359050612ade81612aba565b92915050565b5f805f60608486031215612afb57612afa6121b4565b5b5f84013567ffffffffffffffff811115612b1857612b176121b8565b5b612b2486828701612a9b565b9350506020612b3586828701612ad0565b9250506040612b4686828701612290565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b5f612b7482612b50565b612b7e8185612b5a565b9350612b8e818560208601612870565b612b97816122ea565b840191505092915050565b5f6040820190508181035f830152612bba8185612b6a565b9050612bc96020830184612183565b9392505050565b5f612bda82612750565b9050919050565b612bea81612bd0565b82525050565b5f602082019050612c035f830184612be1565b92915050565b612c12816121bc565b82525050565b5f602082019050612c2b5f830184612c09565b92915050565b612c3a8161223f565b82525050565b5f604082019050612c535f830185612c31565b612c606020830184612183565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612cab57607f821691505b602082108103612cbe57612cbd612c67565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612d207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612ce5565b612d2a8683612ce5565b95508019841693508086168417925050509392505050565b5f612d5c612d57612d528461217a565b612726565b61217a565b9050919050565b5f819050919050565b612d7583612d42565b612d89612d8182612d63565b848454612cf1565b825550505050565b5f90565b612d9d612d91565b612da8818484612d6c565b505050565b5b81811015612dcb57612dc05f82612d95565b600181019050612dae565b5050565b601f821115612e1057612de181612cc4565b612dea84612cd6565b81016020851015612df9578190505b612e0d612e0585612cd6565b830182612dad565b50505b505050565b5f82821c905092915050565b5f612e305f1984600802612e15565b1980831691505092915050565b5f612e488383612e21565b9150826002028217905092915050565b612e6182612856565b67ffffffffffffffff811115612e7a57612e796122fa565b5b612e848254612c94565b612e8f828285612dcf565b5f60209050601f831160018114612ec0575f8415612eae578287015190505b612eb88582612e3d565b865550612f1f565b601f198416612ece86612cc4565b5f5b82811015612ef557848901518255600182019150602085019450602081019050612ed0565b86831015612f125784890151612f0e601f891682612e21565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612f5e8261217a565b9150612f698361217a565b9250828202612f778161217a565b91508282048414831517612f8e57612f8d612f27565b5b5092915050565b7f54504d3a207072696365206d61726b757020746f6f20686967680000000000005f82015250565b5f612fc9601a83612860565b9150612fd482612f95565b602082019050919050565b5f6020820190508181035f830152612ff681612fbd565b9050919050565b7f54504d3a207072696365206d61726b757020746f6f206c6f77000000000000005f82015250565b5f613031601983612860565b915061303c82612ffd565b602082019050919050565b5f6020820190508181035f83015261305e81613025565b9050919050565b61306e8161217a565b82525050565b61307d8161258e565b82525050565b608082015f8201516130975f850182613065565b5060208201516130aa6020850182613065565b5060408201516130bd6040850182613065565b5060608201516130d06060850182613074565b50505050565b5f6080820190506130e95f830184613083565b92915050565b5f81546130fb81612c94565b6131058186612860565b9450600182165f811461311f576001811461313557613167565b60ff198316865281151560200286019350613167565b61313e85612cc4565b5f5b8381101561315f57815481890152600182019150602081019050613140565b808801955050505b50505092915050565b5f60a0820190506131835f8301886126fe565b6131906020830187612183565b81810360408301526131a281866130ef565b90506131b16060830185612a45565b6131be6080830184612a45565b9695505050505050565b5f6040820190506131db5f8301856126fe565b6131e86020830184612183565b9392505050565b6131f881612557565b8114613202575f80fd5b50565b5f81519050613213816131ef565b92915050565b5f6020828403121561322e5761322d6121b4565b5b5f61323b84828501613205565b91505092915050565b5f6020820190506132575f830184612c31565b92915050565b5f8151905061326b8161227a565b92915050565b5f60208284031215613286576132856121b4565b5b5f6132938482850161325d565b91505092915050565b7f53656e646572206e6f7420456e747279506f696e7400000000000000000000005f82015250565b5f6132d0601583612860565b91506132db8261329c565b602082019050919050565b5f6020820190508181035f8301526132fd816132c4565b9050919050565b5f805f806080858703121561331c5761331b6121b4565b5b5f61332987828801612290565b945050602061333a87828801612290565b935050604061334b87828801612290565b925050606061335c87828801612266565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6060820190506133d55f8301866126fe565b6133e260208301856126fe565b6133ef6040830184612183565b949350505050565b5f60608201905061340a5f830186612183565b6134176020830185612183565b6134246040830184612183565b949350505050565b5f80fd5b5f80fd5b5f80fd5b5f80833560016020038436030381126134545761345361342c565b5b80840192508235915067ffffffffffffffff82111561347657613475613430565b5b60208301925060018202360383131561349257613491613434565b5b509250929050565b5f6134a48261217a565b91506134af8361217a565b92508282019050808211156134c7576134c6612f27565b5b92915050565b5f6134d78261217a565b91506134e28361217a565b9250826134f2576134f1613395565b5b828204905092915050565b5f6080820190506135105f830187612183565b61351d6020830186612183565b61352a6040830185612183565b61353760608301846126fe565b95945050505050565b5f80fd5b5f80fd5b5f808585111561355b5761355a613540565b5b8386111561356c5761356b613544565b5b6001850283019150848603905094509492505050565b5f8060408385031215613598576135976121b4565b5b5f6135a5858286016125b5565b92505060206135b6858286016125b5565b9150509250929050565b5f69ffffffffffffffffffff82169050919050565b6135de816135c0565b81146135e8575f80fd5b50565b5f815190506135f9816135d5565b92915050565b5f819050919050565b613611816135ff565b811461361b575f80fd5b50565b5f8151905061362c81613608565b92915050565b5f805f805f60a0868803121561364b5761364a6121b4565b5b5f613658888289016135eb565b95505060206136698882890161361e565b945050604061367a8882890161325d565b935050606061368b8882890161325d565b925050608061369c888289016135eb565b9150509295509295909350565b7f50502d4552433230203a20436861696e6c696e6b207072696365203c3d2030005f82015250565b5f6136dd601f83612860565b91506136e8826136a9565b602082019050919050565b5f6020820190508181035f83015261370a816136d1565b9050919050565b7f50502d4552433230203a205374616c65207072696365000000000000000000005f82015250565b5f613745601683612860565b915061375082613711565b602082019050919050565b5f6020820190508181035f83015261377281613739565b9050919050565b7f45434453413a20696e76616c6964207369676e617475726500000000000000005f82015250565b5f6137ad601883612860565b91506137b882613779565b602082019050919050565b5f6020820190508181035f8301526137da816137a1565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e677468005f82015250565b5f613815601f83612860565b9150613820826137e1565b602082019050919050565b5f6020820190508181035f83015261384281613809565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c5f8201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b5f6138a3602283612860565b91506138ae82613849565b604082019050919050565b5f6020820190508181035f8301526138d081613897565b9050919050565b5f60ff82169050919050565b6138ec816138d7565b82525050565b5f6080820190506139055f8301876126d6565b61391260208301866138e3565b61391f60408301856126d6565b61392c60608301846126d6565b9594505050505056fea264697066735822122058ccc6f71b1a510115f9dc3c96fc21547e278904a70cf3b62c2a4d23d2f792f464736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006926fbff41d234afe0ad2f1c73558afa83d8d8ae0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d2789000000000000000000000000bfaff33db44f752f39ecf99fc153b7e602c8f798000000000000000000000000bfaff33db44f752f39ecf99fc153b7e602c8f79800000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000009c40000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000036a9ac722158d347738f703db8c40a245c01258e000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000063633373831390000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _token (address): 0x6926fbfF41d234aFe0Ad2f1C73558aFA83d8d8AE
Arg [1] : _entryPoint (address): 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
Arg [2] : _tokenOracle (address): 0xbFAFF33DB44f752f39ECf99FC153B7e602c8f798
Arg [3] : _nativeAssetOracle (address): 0xbFAFF33DB44f752f39ECf99FC153B7e602c8f798
Arg [4] : _tokenPaymasterConfig (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [5] : _owner (address): 0x36a9AC722158D347738f703Db8c40A245C01258e
Arg [6] : _signature (string): 637819
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000006926fbff41d234afe0ad2f1c73558afa83d8d8ae
Arg [1] : 0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d2789
Arg [2] : 000000000000000000000000bfaff33db44f752f39ecf99fc153b7e602c8f798
Arg [3] : 000000000000000000000000bfaff33db44f752f39ecf99fc153b7e602c8f798
Arg [4] : 00000000000000000000000000000000000000000000000000000000000f4240
Arg [5] : 00000000000000000000000000000000000000000000000000000000000f4240
Arg [6] : 0000000000000000000000000000000000000000000000000000000000009c40
Arg [7] : 000000000000000000000000000000000000000000000000000000000000003c
Arg [8] : 00000000000000000000000036a9ac722158d347738f703db8c40a245c01258e
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [11] : 3633373831390000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
456:10306:21:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9601:10;9592:31;;;9613:9;9592:31;;;;;;:::i;:::-;;;;;;;;456:10306;;;;;3675:142:13;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3267:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2741:106:21;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3553:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4608:156;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1042:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;857:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3972:501;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10521:238;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3093:109;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;997:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;892:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2293:101:0;;;;;;;;;;;;;:::i;:::-;;1137:45:21;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3208:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3711:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2853:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1638:85:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3319:129:21;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4481:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1460:223:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;485:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4183:85;;;;;;;;;;;;;:::i;:::-;;4496:135;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3905:113;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1082:48:21;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;2989:106:13;;;:::i;:::-;;925:32:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2543:215:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;653:322:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;2963:124:21;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;964:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;830:20;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3830:136;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3675:142:13;1531:13:0;:11;:13::i;:::-;3755:10:13::1;:19;;;3782:9;3793:15;3755:54;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;3675:142:::0;:::o;3267:176::-;1531:13:0;:11;:13::i;:::-;3389:10:13::1;:21;;;3411:15;3428:6;3389:46;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;3267:176:::0;;:::o;2741:106:21:-;1531:13:0;:11;:13::i;:::-;2829:10:21::1;2817:9;:22;;;;;;:::i;:::-;;2741:106:::0;:::o;3553:152::-;1531:13:0;:11;:13::i;:::-;3650:6:21::1;3642:5;;:14;;;;;;;;;;;;;;;;;;3683;3667:13;:30;;;;3553:152:::0;;:::o;4608:156::-;4688:4;1531:13:0;:11;:13::i;:::-;4704:30:21::1;4720:6;4727;4704:15;:30::i;:::-;4752:4;4745:11;;4608:156:::0;;;;:::o;1042:33::-;;;;:::o;857:28::-;;;;:::o;3972:501::-;1531:13:0;:11;:13::i;:::-;4147:17:21::1;;4143:1;:21;;;;:::i;:::-;4106;:33;;;:58;;4084:134;;;;;;;;;;;;:::i;:::-;;;;;;;;;4288:17;;4251:21;:33;;;:54;;4229:129;;;;;;;;;;;;:::i;:::-;;;;;;;;;4392:21;4369:20;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4429:36;4443:21;4429:36;;;;;;:::i;:::-;;;;;;;;3972:501:::0;:::o;10521:238::-;10633:7;10695:6;10702:5;10708:9;10718:10;10729;10684:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10660:91;;;;;;10653:98;;10521:238;;;;;;:::o;3093:109::-;3153:7;1531:13:0;:11;:13::i;:::-;3179:15:21::1;;;;;;;;;;;3172:22;;3093:109:::0;:::o;997:38::-;;;;:::o;892:26::-;;;;;;;;;;;;;:::o;2293:101:0:-;1531:13;:11;:13::i;:::-;2357:30:::1;2384:1;2357:18;:30::i;:::-;2293:101::o:0;1137:45:21:-;;;;;;;;;;;;;;;;;:::o;3208:105::-;1531:13:0;:11;:13::i;:::-;3294:11:21::1;3280;:25;;;;3208:105:::0;:::o;3711:113::-;1531:13:0;:11;:13::i;:::-;3804:12:21::1;3790:11;;:26;;;;;;;;;;;;;;;;;;3711:113:::0;:::o;2853:104::-;2908:13;1531::0;:11;:13::i;:::-;2940:9:21::1;2933:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2853:104:::0;:::o;1638:85:0:-;1684:7;1710:6;;;;;;;;;;;1703:13;;1638:85;:::o;3319:129:21:-;1531:13:0;:11;:13::i;:::-;3423:17:21::1;3403;:37;;;;3319:129:::0;:::o;4481:119::-;1531:13:0;:11;:13::i;:::-;4564:5:21::1;;;;;;;;;;;:14;;;4579:3;4584:7;4564:28;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;4481:119:::0;;:::o;1460:223:13:-;1603:24;:22;:24::i;:::-;1638:37;1646:4;1652:7;;1661:13;1638:7;:37::i;:::-;1460:223;;;;:::o;485:39::-;;;:::o;4183:85::-;1531:13:0;:11;:13::i;:::-;4236:10:13::1;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;4183:85::o:0;4496:135::-;1531:13:0;:11;:13::i;:::-;4582:10:13::1;:24;;;4607:15;4582:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;4496:135:::0;:::o;3905:113::-;3948:7;3975:10;:20;;;4004:4;3975:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3968:42;;3905:113;:::o;1082:48:21:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2989:106:13:-;3034:10;:20;;;3062:9;3081:4;3034:53;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2989:106::o;925:32:21:-;;;;;;;;;;;;;:::o;2543:215:0:-;1531:13;:11;:13::i;:::-;2647:1:::1;2627:22;;:8;:22;;::::0;2623:91:::1;;2700:1;2672:31;;;;;;;;;;;:::i;:::-;;;;;;;;2623:91;2723:28;2742:8;2723:18;:28::i;:::-;2543:215:::0;:::o;653:322:13:-;815:20;837:22;872:24;:22;:24::i;:::-;914:53;939:6;947:10;959:7;914:24;:53::i;:::-;907:60;;;;653:322;;;;;;:::o;2963:124:21:-;1531:13:0;:11;:13::i;:::-;3063:16:21::1;3045:15;;:34;;;;;;;;;;;;;;;;;;2963:124:::0;:::o;964:26::-;;;;:::o;830:20::-;;;;;;;;;;;;;:::o;3830:136::-;1531:13:0;:11;:13::i;:::-;3940:18:21::1;3920:17;;:38;;;;;;;;;;;;;;;;;;3830:136:::0;:::o;1796:162:0:-;1866:12;:10;:12::i;:::-;1855:23;;:7;:5;:7::i;:::-;:23;;;1851:101;;1928:12;:10;:12::i;:::-;1901:40;;;;;;;;;;;:::i;:::-;;;;;;;;1851:101;1796:162::o;4772:155:21:-;4868:6;4847:10;:18;4858:6;4847:18;;;;;;;;;;;;;;;:27;;;;4905:6;4890:29;;;4912:6;4890:29;;;;;;:::i;:::-;;;;;;;;4772:155;;:::o;2912:187:0:-;2985:16;3004:6;;;;;;;;;;;2985:25;;3029:8;3020:6;;:17;;;;;;;;;;;;;;;;;;3083:8;3052:40;;3073:8;3052:40;;;;;;;;;;;;2975:124;2912:187;:::o;4715:137:13:-;4807:10;4785:33;;:10;:33;;;4777:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;4715:137::o;6963:2189:21:-;7117:17;7153:20;7192:28;7239:20;7288:7;;7277:57;;;;;;;:::i;:::-;7098:236;;;;;;;;7363:25;7355:33;;;;;;;;:::i;:::-;;:4;:33;;;;;;;;:::i;:::-;;;7351:118;;7429:12;7414:39;;;7443:9;7414:39;;;;;;:::i;:::-;;;;;;;;7351:118;7485:13;:11;:13::i;:::-;7513:16;7532:47;7544:12;7558:20;7532:11;:47::i;:::-;7513:66;;7594:29;7662:20;:32;;;7641:17;;7627:11;;:31;7626:68;;;;;:::i;:::-;;;7594:100;;7709:26;7794:8;7754:20;:37;;;:48;7738:13;:64;7709:93;;7817:25;7845:53;7856:18;7876:21;7845:10;:53::i;:::-;7817:81;;7929:17;7917:9;:29;7913:1039;;;8156:5;;;;;;;;;;;:14;;;8171:12;8197:17;8185:9;:29;8156:59;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;7913:1039;;;8256:20;8279:10;:24;8290:12;8279:24;;;;;;;;;;;;;;;;8256:47;;8322:22;8386:1;8371:12;:16;8367:570;;;8449:9;8429:17;:29;8412:46;;8481:5;;;;;;;;;;;:18;;;8526:12;8573:4;8605:14;8481:161;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;8693:14;8665:10;:24;8676:12;8665:24;;;;;;;;;;;;;;;;:42;;;;;;;;;;;8367:570;;;8756:5;;;;;;;;;;;:18;;;8801:12;8848:4;8880:14;8756:161;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;8367:570;8237:715;;7913:1039;9012:12;8971:162;;;9043:17;9079:9;9107:11;;8971:162;;;;;;;;:::i;:::-;;;;;;;;7073:2072;;;;;;;;6963:2189;;;;:::o;4935:2020::-;5061:20;5083:22;5147:14;5164:18;:6;:16;:18::i;:::-;5147:35;;5193:20;5216:6;:19;;;5193:42;;5246:28;5277:6;:27;;;5246:58;;5318:17;5336;5355:28;;5387:46;5409:6;:23;;;;;;;;:::i;:::-;5387:21;:46::i;:::-;5317:116;;;;;;;;5446:21;5470:66;5487:6;:13;;;;;;;;;;:::i;:::-;5501:6;:12;;;5514:10;5525;5470:16;:66::i;:::-;5446:90;;5547:12;5562:38;:13;:36;:38::i;:::-;5547:53;;5634:27;5647:13;;5634:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:4;:12;;:27;;;;:::i;:::-;5615:46;;:15;;;;;;;;;;;:46;;;5611:197;;5710:6;5683:39;;;5717:4;5683:39;;;;;;:::i;:::-;;;;;;;;5748:47;5768:4;5773:10;5784;5748:19;:47::i;:::-;5737:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;5611:197;5820:20;5843:10;:18;5854:6;5843:18;;;;;;;;;;;;;;;;5820:41;;5872:19;5906:23;5991:12;5951:20;:37;;;:52;;;;:::i;:::-;5932:15;:72;;;;:::i;:::-;5906:98;;6015:29;6083:20;:32;;;6062:17;;6048:11;;:31;;;;:::i;:::-;6047:68;;;;:::i;:::-;6015:100;;6147:1;6132:12;:16;6128:448;;;6179:49;6190:15;6206:21;6179:10;:49::i;:::-;6165:63;;6243:5;;;;;;;;;;;:18;;;6280:6;6313:4;6337:11;6243:120;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;6400:11;6378:10;:18;6389:6;6378:18;;;;;;;;;;;;;;;;:33;;;;;;;:::i;:::-;;;;;;;;6128:448;;;6444:5;;;;;;;;;;;:18;;;6481:6;6514:4;6538:11;6444:120;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;6128:448;6623:11;6649:12;6676:20;6711:6;6598:130;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;6588:140;;6781:6;6744:136;;;6802:11;6828:15;6858:11;;6744:136;;;;;;;;:::i;:::-;;;;;;;;6899:7;6907:39;6927:5;6933:10;6944:1;6907:19;:39::i;:::-;6891:56;;;;;;;;;;;;;;;;;4935:2020;;;;;;;:::o;655:96:4:-;708:7;734:10;727:17;;655:96;:::o;3454:93:21:-;3510:29;3521:17;;;;;;;;;;;3510:10;:29::i;:::-;3496:43;;:11;:43;;;;3454:93::o;9160:267::-;9256:7;9295:20;9279:12;:36;9275:88;;9339:12;9332:19;;;;9275:88;9380:39;9384:12;9398:20;9380:3;:39::i;:::-;9373:46;;9160:267;;;;;:::o;10005:155::-;10079:7;10141:11;;10125:13;;10116:5;10107:6;:14;;;;:::i;:::-;10106:32;;;;:::i;:::-;:46;;;;:::i;:::-;10099:53;;10005:155;;;;:::o;1903:326:20:-;1992:7;2012:12;2164:6;2151:20;2143:28;;2215:4;2192:29;;;1903:326;;;:::o;10168:343:21:-;10253:17;10271;10290:28;;10331:24;;10358:16;;10375:2;10358:23;10378:2;10358:23;;;;;;;:::i;:::-;10331:50;;;;10429:9;;10418:37;;;;;;;:::i;:::-;10392:63;;;;;;;;10482:16;;10499:2;10482:21;;;;;;;;;:::i;:::-;10466:37;;;;10320:191;;10168:343;;;;;;;:::o;7120:396:8:-;7189:15;7389:34;7383:4;7376:48;7450:4;7444;7437:18;7495:4;7489;7479:21;7468:32;;7120:396;;;:::o;3661:227::-;3739:7;3759:17;3778:18;3800:27;3811:4;3817:9;3800:10;:27::i;:::-;3758:69;;;;3837:18;3849:5;3837:11;:18::i;:::-;3872:9;3865:16;;;;3661:227;;;;:::o;2614:258:14:-;2730:7;2858:8;2842:10;2834:19;;:33;;2817:3;2802:10;2794:19;;:26;;2763:9;:17;;2779:1;2763:17;;;2775:1;2763:17;2762:59;;;:106;2746:122;;2614:258;;;;;:::o;9639:358:21:-;9699:13;9726:14;9742:13;9759:22;9785:7;:23;;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9725:85;;;;;;;;9838:1;9829:6;:10;9821:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;9913:7;9894:26;;:15;:26;;;;9886:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;9981:6;9958:31;;9714:283;;;9639:358;;;:::o;9435:106::-;9493:7;9524:1;9520;:5;:13;;9532:1;9520:13;;;9528:1;9520:13;9513:20;;9435:106;;;;:::o;2145:730:8:-;2226:7;2235:12;2283:2;2263:9;:16;:22;2259:610;;2301:9;2324;2347:7;2599:4;2588:9;2584:20;2578:27;2573:32;;2648:4;2637:9;2633:20;2627:27;2622:32;;2705:4;2694:9;2690:20;2684:27;2681:1;2676:36;2671:41;;2746:25;2757:4;2763:1;2766;2769;2746:10;:25::i;:::-;2739:32;;;;;;;;;2259:610;2818:1;2822:35;2802:56;;;;2145:730;;;;;;:::o;570:511::-;647:20;638:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;634:441;683:7;634:441;743:29;734:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;730:345;;788:34;;;;;;;;;;:::i;:::-;;;;;;;;730:345;852:35;843:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;839:236;;903:41;;;;;;;;;;:::i;:::-;;;;;;;;839:236;974:30;965:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;961:114;;1020:44;;;;;;;;;;:::i;:::-;;;;;;;;961:114;570:511;;:::o;5009:1456::-;5097:7;5106:12;6021:66;6016:1;6008:10;;:79;6004:161;;;6119:1;6123:30;6103:51;;;;;;6004:161;6259:14;6276:24;6286:4;6292:1;6295;6298;6276:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6259:41;;6332:1;6314:20;;:6;:20;;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;6437:20;6421:37;;;;;5009:1456;;;;;;;;:::o;7:77:23:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o;442:75::-;475:6;508:2;502:9;492:19;;442:75;:::o;523:117::-;632:1;629;622:12;646:117;755:1;752;745:12;769:93;805:7;845:10;838:5;834:22;823:33;;769:93;;;:::o;868:120::-;940:23;957:5;940:23;:::i;:::-;933:5;930:34;920:62;;978:1;975;968:12;920:62;868:120;:::o;994:137::-;1039:5;1077:6;1064:20;1055:29;;1093:32;1119:5;1093:32;:::i;:::-;994:137;;;;:::o;1137:327::-;1195:6;1244:2;1232:9;1223:7;1219:23;1215:32;1212:119;;;1250:79;;:::i;:::-;1212:119;1370:1;1395:52;1439:7;1430:6;1419:9;1415:22;1395:52;:::i;:::-;1385:62;;1341:116;1137:327;;;;:::o;1470:126::-;1507:7;1547:42;1540:5;1536:54;1525:65;;1470:126;;;:::o;1602:104::-;1647:7;1676:24;1694:5;1676:24;:::i;:::-;1665:35;;1602:104;;;:::o;1712:138::-;1793:32;1819:5;1793:32;:::i;:::-;1786:5;1783:43;1773:71;;1840:1;1837;1830:12;1773:71;1712:138;:::o;1856:155::-;1910:5;1948:6;1935:20;1926:29;;1964:41;1999:5;1964:41;:::i;:::-;1856:155;;;;:::o;2017:122::-;2090:24;2108:5;2090:24;:::i;:::-;2083:5;2080:35;2070:63;;2129:1;2126;2119:12;2070:63;2017:122;:::o;2145:139::-;2191:5;2229:6;2216:20;2207:29;;2245:33;2272:5;2245:33;:::i;:::-;2145:139;;;;:::o;2290:490::-;2366:6;2374;2423:2;2411:9;2402:7;2398:23;2394:32;2391:119;;;2429:79;;:::i;:::-;2391:119;2549:1;2574:61;2627:7;2618:6;2607:9;2603:22;2574:61;:::i;:::-;2564:71;;2520:125;2684:2;2710:53;2755:7;2746:6;2735:9;2731:22;2710:53;:::i;:::-;2700:63;;2655:118;2290:490;;;;;:::o;2786:117::-;2895:1;2892;2885:12;2909:117;3018:1;3015;3008:12;3032:102;3073:6;3124:2;3120:7;3115:2;3108:5;3104:14;3100:28;3090:38;;3032:102;;;:::o;3140:180::-;3188:77;3185:1;3178:88;3285:4;3282:1;3275:15;3309:4;3306:1;3299:15;3326:281;3409:27;3431:4;3409:27;:::i;:::-;3401:6;3397:40;3539:6;3527:10;3524:22;3503:18;3491:10;3488:34;3485:62;3482:88;;;3550:18;;:::i;:::-;3482:88;3590:10;3586:2;3579:22;3369:238;3326:281;;:::o;3613:129::-;3647:6;3674:20;;:::i;:::-;3664:30;;3703:33;3731:4;3723:6;3703:33;:::i;:::-;3613:129;;;:::o;3748:308::-;3810:4;3900:18;3892:6;3889:30;3886:56;;;3922:18;;:::i;:::-;3886:56;3960:29;3982:6;3960:29;:::i;:::-;3952:37;;4044:4;4038;4034:15;4026:23;;3748:308;;;:::o;4062:146::-;4159:6;4154:3;4149;4136:30;4200:1;4191:6;4186:3;4182:16;4175:27;4062:146;;;:::o;4214:425::-;4292:5;4317:66;4333:49;4375:6;4333:49;:::i;:::-;4317:66;:::i;:::-;4308:75;;4406:6;4399:5;4392:21;4444:4;4437:5;4433:16;4482:3;4473:6;4468:3;4464:16;4461:25;4458:112;;;4489:79;;:::i;:::-;4458:112;4579:54;4626:6;4621:3;4616;4579:54;:::i;:::-;4298:341;4214:425;;;;;:::o;4659:340::-;4715:5;4764:3;4757:4;4749:6;4745:17;4741:27;4731:122;;4772:79;;:::i;:::-;4731:122;4889:6;4876:20;4914:79;4989:3;4981:6;4974:4;4966:6;4962:17;4914:79;:::i;:::-;4905:88;;4721:278;4659:340;;;;:::o;5005:509::-;5074:6;5123:2;5111:9;5102:7;5098:23;5094:32;5091:119;;;5129:79;;:::i;:::-;5091:119;5277:1;5266:9;5262:17;5249:31;5307:18;5299:6;5296:30;5293:117;;;5329:79;;:::i;:::-;5293:117;5434:63;5489:7;5480:6;5469:9;5465:22;5434:63;:::i;:::-;5424:73;;5220:287;5005:509;;;;:::o;5520:96::-;5557:7;5586:24;5604:5;5586:24;:::i;:::-;5575:35;;5520:96;;;:::o;5622:110::-;5673:7;5702:24;5720:5;5702:24;:::i;:::-;5691:35;;5622:110;;;:::o;5738:150::-;5825:38;5857:5;5825:38;:::i;:::-;5818:5;5815:49;5805:77;;5878:1;5875;5868:12;5805:77;5738:150;:::o;5894:167::-;5954:5;5992:6;5979:20;5970:29;;6008:47;6049:5;6008:47;:::i;:::-;5894:167;;;;:::o;6067:502::-;6149:6;6157;6206:2;6194:9;6185:7;6181:23;6177:32;6174:119;;;6212:79;;:::i;:::-;6174:119;6332:1;6357:67;6416:7;6407:6;6396:9;6392:22;6357:67;:::i;:::-;6347:77;;6303:131;6473:2;6499:53;6544:7;6535:6;6524:9;6520:22;6499:53;:::i;:::-;6489:63;;6444:118;6067:502;;;;;:::o;6575:122::-;6648:24;6666:5;6648:24;:::i;:::-;6641:5;6638:35;6628:63;;6687:1;6684;6677:12;6628:63;6575:122;:::o;6703:139::-;6749:5;6787:6;6774:20;6765:29;;6803:33;6830:5;6803:33;:::i;:::-;6703:139;;;;:::o;6848:474::-;6916:6;6924;6973:2;6961:9;6952:7;6948:23;6944:32;6941:119;;;6979:79;;:::i;:::-;6941:119;7099:1;7124:53;7169:7;7160:6;7149:9;7145:22;7124:53;:::i;:::-;7114:63;;7070:117;7226:2;7252:53;7297:7;7288:6;7277:9;7273:22;7252:53;:::i;:::-;7242:63;;7197:118;6848:474;;;;;:::o;7328:90::-;7362:7;7405:5;7398:13;7391:21;7380:32;;7328:90;;;:::o;7424:109::-;7505:21;7520:5;7505:21;:::i;:::-;7500:3;7493:34;7424:109;;:::o;7539:210::-;7626:4;7664:2;7653:9;7649:18;7641:26;;7677:65;7739:1;7728:9;7724:17;7715:6;7677:65;:::i;:::-;7539:210;;;;:::o;7755:117::-;7864:1;7861;7854:12;8001:97;8037:7;8077:14;8070:5;8066:26;8055:37;;8001:97;;;:::o;8104:120::-;8176:23;8193:5;8176:23;:::i;:::-;8169:5;8166:34;8156:62;;8214:1;8211;8204:12;8156:62;8104:120;:::o;8230:137::-;8275:5;8313:6;8300:20;8291:29;;8329:32;8355:5;8329:32;:::i;:::-;8230:137;;;;:::o;8421:950::-;8508:5;8552:4;8540:9;8535:3;8531:19;8527:30;8524:117;;;8560:79;;:::i;:::-;8524:117;8659:21;8675:4;8659:21;:::i;:::-;8650:30;;8746:1;8786:49;8831:3;8822:6;8811:9;8807:22;8786:49;:::i;:::-;8779:4;8772:5;8768:16;8761:75;8690:157;8922:2;8963:49;9008:3;8999:6;8988:9;8984:22;8963:49;:::i;:::-;8956:4;8949:5;8945:16;8938:75;8857:167;9095:2;9136:49;9181:3;9172:6;9161:9;9157:22;9136:49;:::i;:::-;9129:4;9122:5;9118:16;9111:75;9034:163;9263:2;9304:48;9348:3;9339:6;9328:9;9324:22;9304:48;:::i;:::-;9297:4;9290:5;9286:16;9279:74;9207:157;8421:950;;;;:::o;9377:406::-;9474:6;9523:3;9511:9;9502:7;9498:23;9494:33;9491:120;;;9530:79;;:::i;:::-;9491:120;9650:1;9675:91;9758:7;9749:6;9738:9;9734:22;9675:91;:::i;:::-;9665:101;;9621:155;9377:406;;;;:::o;9789:761::-;9873:6;9881;9889;9897;9946:3;9934:9;9925:7;9921:23;9917:33;9914:120;;;9953:79;;:::i;:::-;9914:120;10073:1;10098:53;10143:7;10134:6;10123:9;10119:22;10098:53;:::i;:::-;10088:63;;10044:117;10200:2;10226:53;10271:7;10262:6;10251:9;10247:22;10226:53;:::i;:::-;10216:63;;10171:118;10328:2;10354:52;10398:7;10389:6;10378:9;10374:22;10354:52;:::i;:::-;10344:62;;10299:117;10455:2;10481:52;10525:7;10516:6;10505:9;10501:22;10481:52;:::i;:::-;10471:62;;10426:117;9789:761;;;;;;;:::o;10556:77::-;10593:7;10622:5;10611:16;;10556:77;;;:::o;10639:118::-;10726:24;10744:5;10726:24;:::i;:::-;10721:3;10714:37;10639:118;;:::o;10763:222::-;10856:4;10894:2;10883:9;10879:18;10871:26;;10907:71;10975:1;10964:9;10960:17;10951:6;10907:71;:::i;:::-;10763:222;;;;:::o;10991:118::-;11078:24;11096:5;11078:24;:::i;:::-;11073:3;11066:37;10991:118;;:::o;11115:222::-;11208:4;11246:2;11235:9;11231:18;11223:26;;11259:71;11327:1;11316:9;11312:17;11303:6;11259:71;:::i;:::-;11115:222;;;;:::o;11343:60::-;11371:3;11392:5;11385:12;;11343:60;;;:::o;11409:142::-;11459:9;11492:53;11510:34;11519:24;11537:5;11519:24;:::i;:::-;11510:34;:::i;:::-;11492:53;:::i;:::-;11479:66;;11409:142;;;:::o;11557:126::-;11607:9;11640:37;11671:5;11640:37;:::i;:::-;11627:50;;11557:126;;;:::o;11689:142::-;11755:9;11788:37;11819:5;11788:37;:::i;:::-;11775:50;;11689:142;;;:::o;11837:163::-;11940:53;11987:5;11940:53;:::i;:::-;11935:3;11928:66;11837:163;;:::o;12006:254::-;12115:4;12153:2;12142:9;12138:18;12130:26;;12166:87;12250:1;12239:9;12235:17;12226:6;12166:87;:::i;:::-;12006:254;;;;:::o;12266:329::-;12325:6;12374:2;12362:9;12353:7;12349:23;12345:32;12342:119;;;12380:79;;:::i;:::-;12342:119;12500:1;12525:53;12570:7;12561:6;12550:9;12546:22;12525:53;:::i;:::-;12515:63;;12471:117;12266:329;;;;:::o;12601:::-;12660:6;12709:2;12697:9;12688:7;12684:23;12680:32;12677:119;;;12715:79;;:::i;:::-;12677:119;12835:1;12860:53;12905:7;12896:6;12885:9;12881:22;12860:53;:::i;:::-;12850:63;;12806:117;12601:329;;;;:::o;12936:112::-;12989:7;13018:24;13036:5;13018:24;:::i;:::-;13007:35;;12936:112;;;:::o;13054:154::-;13143:40;13177:5;13143:40;:::i;:::-;13136:5;13133:51;13123:79;;13198:1;13195;13188:12;13123:79;13054:154;:::o;13214:171::-;13276:5;13314:6;13301:20;13292:29;;13330:49;13373:5;13330:49;:::i;:::-;13214:171;;;;:::o;13391:361::-;13466:6;13515:2;13503:9;13494:7;13490:23;13486:32;13483:119;;;13521:79;;:::i;:::-;13483:119;13641:1;13666:69;13727:7;13718:6;13707:9;13703:22;13666:69;:::i;:::-;13656:79;;13612:133;13391:361;;;;:::o;13758:99::-;13810:6;13844:5;13838:12;13828:22;;13758:99;;;:::o;13863:169::-;13947:11;13981:6;13976:3;13969:19;14021:4;14016:3;14012:14;13997:29;;13863:169;;;;:::o;14038:246::-;14119:1;14129:113;14143:6;14140:1;14137:13;14129:113;;;14228:1;14223:3;14219:11;14213:18;14209:1;14204:3;14200:11;14193:39;14165:2;14162:1;14158:10;14153:15;;14129:113;;;14276:1;14267:6;14262:3;14258:16;14251:27;14100:184;14038:246;;;:::o;14290:377::-;14378:3;14406:39;14439:5;14406:39;:::i;:::-;14461:71;14525:6;14520:3;14461:71;:::i;:::-;14454:78;;14541:65;14599:6;14594:3;14587:4;14580:5;14576:16;14541:65;:::i;:::-;14631:29;14653:6;14631:29;:::i;:::-;14626:3;14622:39;14615:46;;14382:285;14290:377;;;;:::o;14673:313::-;14786:4;14824:2;14813:9;14809:18;14801:26;;14873:9;14867:4;14863:20;14859:1;14848:9;14844:17;14837:47;14901:78;14974:4;14965:6;14901:78;:::i;:::-;14893:86;;14673:313;;;;:::o;14992:114::-;15080:1;15073:5;15070:12;15060:40;;15096:1;15093;15086:12;15060:40;14992:114;:::o;15112:169::-;15173:5;15211:6;15198:20;15189:29;;15227:48;15269:5;15227:48;:::i;:::-;15112:169;;;;:::o;15287:117::-;15396:1;15393;15386:12;15410:117;15519:1;15516;15509:12;15546:552;15603:8;15613:6;15663:3;15656:4;15648:6;15644:17;15640:27;15630:122;;15671:79;;:::i;:::-;15630:122;15784:6;15771:20;15761:30;;15814:18;15806:6;15803:30;15800:117;;;15836:79;;:::i;:::-;15800:117;15950:4;15942:6;15938:17;15926:29;;16004:3;15996:4;15988:6;15984:17;15974:8;15970:32;15967:41;15964:128;;;16011:79;;:::i;:::-;15964:128;15546:552;;;;;:::o;16104:847::-;16207:6;16215;16223;16231;16280:2;16268:9;16259:7;16255:23;16251:32;16248:119;;;16286:79;;:::i;:::-;16248:119;16406:1;16431:68;16491:7;16482:6;16471:9;16467:22;16431:68;:::i;:::-;16421:78;;16377:132;16576:2;16565:9;16561:18;16548:32;16607:18;16599:6;16596:30;16593:117;;;16629:79;;:::i;:::-;16593:117;16742:64;16798:7;16789:6;16778:9;16774:22;16742:64;:::i;:::-;16724:82;;;;16519:297;16855:2;16881:53;16926:7;16917:6;16906:9;16902:22;16881:53;:::i;:::-;16871:63;;16826:118;16104:847;;;;;;;:::o;16957:146::-;17027:9;17060:37;17091:5;17060:37;:::i;:::-;17047:50;;16957:146;;;:::o;17109:171::-;17216:57;17267:5;17216:57;:::i;:::-;17211:3;17204:70;17109:171;;:::o;17286:262::-;17399:4;17437:2;17426:9;17422:18;17414:26;;17450:91;17538:1;17527:9;17523:17;17514:6;17450:91;:::i;:::-;17286:262;;;;:::o;17554:345::-;17621:6;17670:2;17658:9;17649:7;17645:23;17641:32;17638:119;;;17676:79;;:::i;:::-;17638:119;17796:1;17821:61;17874:7;17865:6;17854:9;17850:22;17821:61;:::i;:::-;17811:71;;17767:125;17554:345;;;;:::o;17905:115::-;17990:23;18007:5;17990:23;:::i;:::-;17985:3;17978:36;17905:115;;:::o;18026:549::-;18201:4;18239:3;18228:9;18224:19;18216:27;;18253:71;18321:1;18310:9;18306:17;18297:6;18253:71;:::i;:::-;18334:72;18402:2;18391:9;18387:18;18378:6;18334:72;:::i;:::-;18416;18484:2;18473:9;18469:18;18460:6;18416:72;:::i;:::-;18498:70;18564:2;18553:9;18549:18;18540:6;18498:70;:::i;:::-;18026:549;;;;;;;:::o;18581:117::-;18690:1;18687;18680:12;18732:238;18811:5;18852:3;18843:6;18838:3;18834:16;18830:26;18827:113;;;18859:79;;:::i;:::-;18827:113;18958:6;18949:15;;18732:238;;;;:::o;18976:122::-;19049:24;19067:5;19049:24;:::i;:::-;19042:5;19039:35;19029:63;;19088:1;19085;19078:12;19029:63;18976:122;:::o;19104:139::-;19150:5;19188:6;19175:20;19166:29;;19204:33;19231:5;19204:33;:::i;:::-;19104:139;;;;:::o;19249:845::-;19359:6;19367;19375;19424:2;19412:9;19403:7;19399:23;19395:32;19392:119;;;19430:79;;:::i;:::-;19392:119;19578:1;19567:9;19563:17;19550:31;19608:18;19600:6;19597:30;19594:117;;;19630:79;;:::i;:::-;19594:117;19735:86;19813:7;19804:6;19793:9;19789:22;19735:86;:::i;:::-;19725:96;;19521:310;19870:2;19896:53;19941:7;19932:6;19921:9;19917:22;19896:53;:::i;:::-;19886:63;;19841:118;19998:2;20024:53;20069:7;20060:6;20049:9;20045:22;20024:53;:::i;:::-;20014:63;;19969:118;19249:845;;;;;:::o;20100:98::-;20151:6;20185:5;20179:12;20169:22;;20100:98;;;:::o;20204:168::-;20287:11;20321:6;20316:3;20309:19;20361:4;20356:3;20352:14;20337:29;;20204:168;;;;:::o;20378:373::-;20464:3;20492:38;20524:5;20492:38;:::i;:::-;20546:70;20609:6;20604:3;20546:70;:::i;:::-;20539:77;;20625:65;20683:6;20678:3;20671:4;20664:5;20660:16;20625:65;:::i;:::-;20715:29;20737:6;20715:29;:::i;:::-;20710:3;20706:39;20699:46;;20468:283;20378:373;;;;:::o;20757:419::-;20896:4;20934:2;20923:9;20919:18;20911:26;;20983:9;20977:4;20973:20;20969:1;20958:9;20954:17;20947:47;21011:76;21082:4;21073:6;21011:76;:::i;:::-;21003:84;;21097:72;21165:2;21154:9;21150:18;21141:6;21097:72;:::i;:::-;20757:419;;;;;:::o;21182:140::-;21246:9;21279:37;21310:5;21279:37;:::i;:::-;21266:50;;21182:140;;;:::o;21328:159::-;21429:51;21474:5;21429:51;:::i;:::-;21424:3;21417:64;21328:159;;:::o;21493:250::-;21600:4;21638:2;21627:9;21623:18;21615:26;;21651:85;21733:1;21722:9;21718:17;21709:6;21651:85;:::i;:::-;21493:250;;;;:::o;21749:115::-;21834:23;21851:5;21834:23;:::i;:::-;21829:3;21822:36;21749:115;;:::o;21870:218::-;21961:4;21999:2;21988:9;21984:18;21976:26;;22012:69;22078:1;22067:9;22063:17;22054:6;22012:69;:::i;:::-;21870:218;;;;:::o;22094:142::-;22197:32;22223:5;22197:32;:::i;:::-;22192:3;22185:45;22094:142;;:::o;22242:364::-;22379:4;22417:2;22406:9;22402:18;22394:26;;22430:87;22514:1;22503:9;22499:17;22490:6;22430:87;:::i;:::-;22527:72;22595:2;22584:9;22580:18;22571:6;22527:72;:::i;:::-;22242:364;;;;;:::o;22612:180::-;22660:77;22657:1;22650:88;22757:4;22754:1;22747:15;22781:4;22778:1;22771:15;22798:320;22842:6;22879:1;22873:4;22869:12;22859:22;;22926:1;22920:4;22916:12;22947:18;22937:81;;23003:4;22995:6;22991:17;22981:27;;22937:81;23065:2;23057:6;23054:14;23034:18;23031:38;23028:84;;23084:18;;:::i;:::-;23028:84;22849:269;22798:320;;;:::o;23124:141::-;23173:4;23196:3;23188:11;;23219:3;23216:1;23209:14;23253:4;23250:1;23240:18;23232:26;;23124:141;;;:::o;23271:93::-;23308:6;23355:2;23350;23343:5;23339:14;23335:23;23325:33;;23271:93;;;:::o;23370:107::-;23414:8;23464:5;23458:4;23454:16;23433:37;;23370:107;;;;:::o;23483:393::-;23552:6;23602:1;23590:10;23586:18;23625:97;23655:66;23644:9;23625:97;:::i;:::-;23743:39;23773:8;23762:9;23743:39;:::i;:::-;23731:51;;23815:4;23811:9;23804:5;23800:21;23791:30;;23864:4;23854:8;23850:19;23843:5;23840:30;23830:40;;23559:317;;23483:393;;;;;:::o;23882:142::-;23932:9;23965:53;23983:34;23992:24;24010:5;23992:24;:::i;:::-;23983:34;:::i;:::-;23965:53;:::i;:::-;23952:66;;23882:142;;;:::o;24030:75::-;24073:3;24094:5;24087:12;;24030:75;;;:::o;24111:269::-;24221:39;24252:7;24221:39;:::i;:::-;24282:91;24331:41;24355:16;24331:41;:::i;:::-;24323:6;24316:4;24310:11;24282:91;:::i;:::-;24276:4;24269:105;24187:193;24111:269;;;:::o;24386:73::-;24431:3;24386:73;:::o;24465:189::-;24542:32;;:::i;:::-;24583:65;24641:6;24633;24627:4;24583:65;:::i;:::-;24518:136;24465:189;;:::o;24660:186::-;24720:120;24737:3;24730:5;24727:14;24720:120;;;24791:39;24828:1;24821:5;24791:39;:::i;:::-;24764:1;24757:5;24753:13;24744:22;;24720:120;;;24660:186;;:::o;24852:543::-;24953:2;24948:3;24945:11;24942:446;;;24987:38;25019:5;24987:38;:::i;:::-;25071:29;25089:10;25071:29;:::i;:::-;25061:8;25057:44;25254:2;25242:10;25239:18;25236:49;;;25275:8;25260:23;;25236:49;25298:80;25354:22;25372:3;25354:22;:::i;:::-;25344:8;25340:37;25327:11;25298:80;:::i;:::-;24957:431;;24942:446;24852:543;;;:::o;25401:117::-;25455:8;25505:5;25499:4;25495:16;25474:37;;25401:117;;;;:::o;25524:169::-;25568:6;25601:51;25649:1;25645:6;25637:5;25634:1;25630:13;25601:51;:::i;:::-;25597:56;25682:4;25676;25672:15;25662:25;;25575:118;25524:169;;;;:::o;25698:295::-;25774:4;25920:29;25945:3;25939:4;25920:29;:::i;:::-;25912:37;;25982:3;25979:1;25975:11;25969:4;25966:21;25958:29;;25698:295;;;;:::o;25998:1395::-;26115:37;26148:3;26115:37;:::i;:::-;26217:18;26209:6;26206:30;26203:56;;;26239:18;;:::i;:::-;26203:56;26283:38;26315:4;26309:11;26283:38;:::i;:::-;26368:67;26428:6;26420;26414:4;26368:67;:::i;:::-;26462:1;26486:4;26473:17;;26518:2;26510:6;26507:14;26535:1;26530:618;;;;27192:1;27209:6;27206:77;;;27258:9;27253:3;27249:19;27243:26;27234:35;;27206:77;27309:67;27369:6;27362:5;27309:67;:::i;:::-;27303:4;27296:81;27165:222;26500:887;;26530:618;26582:4;26578:9;26570:6;26566:22;26616:37;26648:4;26616:37;:::i;:::-;26675:1;26689:208;26703:7;26700:1;26697:14;26689:208;;;26782:9;26777:3;26773:19;26767:26;26759:6;26752:42;26833:1;26825:6;26821:14;26811:24;;26880:2;26869:9;26865:18;26852:31;;26726:4;26723:1;26719:12;26714:17;;26689:208;;;26925:6;26916:7;26913:19;26910:179;;;26983:9;26978:3;26974:19;26968:26;27026:48;27068:4;27060:6;27056:17;27045:9;27026:48;:::i;:::-;27018:6;27011:64;26933:156;26910:179;27135:1;27131;27123:6;27119:14;27115:22;27109:4;27102:36;26537:611;;;26500:887;;26090:1303;;;25998:1395;;:::o;27399:180::-;27447:77;27444:1;27437:88;27544:4;27541:1;27534:15;27568:4;27565:1;27558:15;27585:410;27625:7;27648:20;27666:1;27648:20;:::i;:::-;27643:25;;27682:20;27700:1;27682:20;:::i;:::-;27677:25;;27737:1;27734;27730:9;27759:30;27777:11;27759:30;:::i;:::-;27748:41;;27938:1;27929:7;27925:15;27922:1;27919:22;27899:1;27892:9;27872:83;27849:139;;27968:18;;:::i;:::-;27849:139;27633:362;27585:410;;;;:::o;28001:176::-;28141:28;28137:1;28129:6;28125:14;28118:52;28001:176;:::o;28183:366::-;28325:3;28346:67;28410:2;28405:3;28346:67;:::i;:::-;28339:74;;28422:93;28511:3;28422:93;:::i;:::-;28540:2;28535:3;28531:12;28524:19;;28183:366;;;:::o;28555:419::-;28721:4;28759:2;28748:9;28744:18;28736:26;;28808:9;28802:4;28798:20;28794:1;28783:9;28779:17;28772:47;28836:131;28962:4;28836:131;:::i;:::-;28828:139;;28555:419;;;:::o;28980:175::-;29120:27;29116:1;29108:6;29104:14;29097:51;28980:175;:::o;29161:366::-;29303:3;29324:67;29388:2;29383:3;29324:67;:::i;:::-;29317:74;;29400:93;29489:3;29400:93;:::i;:::-;29518:2;29513:3;29509:12;29502:19;;29161:366;;;:::o;29533:419::-;29699:4;29737:2;29726:9;29722:18;29714:26;;29786:9;29780:4;29776:20;29772:1;29761:9;29757:17;29750:47;29814:131;29940:4;29814:131;:::i;:::-;29806:139;;29533:419;;;:::o;29958:108::-;30035:24;30053:5;30035:24;:::i;:::-;30030:3;30023:37;29958:108;;:::o;30072:105::-;30147:23;30164:5;30147:23;:::i;:::-;30142:3;30135:36;30072:105;;:::o;30275:921::-;30448:4;30443:3;30439:14;30542:4;30535:5;30531:16;30525:23;30561:63;30618:4;30613:3;30609:14;30595:12;30561:63;:::i;:::-;30463:171;30732:4;30725:5;30721:16;30715:23;30751:63;30808:4;30803:3;30799:14;30785:12;30751:63;:::i;:::-;30644:180;30918:4;30911:5;30907:16;30901:23;30937:63;30994:4;30989:3;30985:14;30971:12;30937:63;:::i;:::-;30834:176;31099:4;31092:5;31088:16;31082:23;31118:61;31173:4;31168:3;31164:14;31150:12;31118:61;:::i;:::-;31020:169;30417:779;30275:921;;:::o;31202:375::-;31371:4;31409:3;31398:9;31394:19;31386:27;;31423:147;31567:1;31556:9;31552:17;31543:6;31423:147;:::i;:::-;31202:375;;;;:::o;31607:831::-;31692:3;31729:5;31723:12;31758:36;31784:9;31758:36;:::i;:::-;31810:71;31874:6;31869:3;31810:71;:::i;:::-;31803:78;;31912:1;31901:9;31897:17;31928:1;31923:164;;;;32101:1;32096:336;;;;31890:542;;31923:164;32007:4;32003:9;31992;31988:25;31983:3;31976:38;32067:6;32060:14;32053:22;32047:4;32043:33;32038:3;32034:43;32027:50;;31923:164;;32096:336;32163:38;32195:5;32163:38;:::i;:::-;32223:1;32237:154;32251:6;32248:1;32245:13;32237:154;;;32325:7;32319:14;32315:1;32310:3;32306:11;32299:35;32375:1;32366:7;32362:15;32351:26;;32273:4;32270:1;32266:12;32261:17;;32237:154;;;32420:1;32415:3;32411:11;32404:18;;32103:329;;31890:542;;31696:742;;31607:831;;;;:::o;32444:741::-;32662:4;32700:3;32689:9;32685:19;32677:27;;32714:71;32782:1;32771:9;32767:17;32758:6;32714:71;:::i;:::-;32795:72;32863:2;32852:9;32848:18;32839:6;32795:72;:::i;:::-;32914:9;32908:4;32904:20;32899:2;32888:9;32884:18;32877:48;32942:75;33012:4;33003:6;32942:75;:::i;:::-;32934:83;;33027:70;33093:2;33082:9;33078:18;33069:6;33027:70;:::i;:::-;33107:71;33173:3;33162:9;33158:19;33149:6;33107:71;:::i;:::-;32444:741;;;;;;;;:::o;33191:332::-;33312:4;33350:2;33339:9;33335:18;33327:26;;33363:71;33431:1;33420:9;33416:17;33407:6;33363:71;:::i;:::-;33444:72;33512:2;33501:9;33497:18;33488:6;33444:72;:::i;:::-;33191:332;;;;;:::o;33529:116::-;33599:21;33614:5;33599:21;:::i;:::-;33592:5;33589:32;33579:60;;33635:1;33632;33625:12;33579:60;33529:116;:::o;33651:137::-;33705:5;33736:6;33730:13;33721:22;;33752:30;33776:5;33752:30;:::i;:::-;33651:137;;;;:::o;33794:345::-;33861:6;33910:2;33898:9;33889:7;33885:23;33881:32;33878:119;;;33916:79;;:::i;:::-;33878:119;34036:1;34061:61;34114:7;34105:6;34094:9;34090:22;34061:61;:::i;:::-;34051:71;;34007:125;33794:345;;;;:::o;34145:254::-;34254:4;34292:2;34281:9;34277:18;34269:26;;34305:87;34389:1;34378:9;34374:17;34365:6;34305:87;:::i;:::-;34145:254;;;;:::o;34405:143::-;34462:5;34493:6;34487:13;34478:22;;34509:33;34536:5;34509:33;:::i;:::-;34405:143;;;;:::o;34554:351::-;34624:6;34673:2;34661:9;34652:7;34648:23;34644:32;34641:119;;;34679:79;;:::i;:::-;34641:119;34799:1;34824:64;34880:7;34871:6;34860:9;34856:22;34824:64;:::i;:::-;34814:74;;34770:128;34554:351;;;;:::o;34911:171::-;35051:23;35047:1;35039:6;35035:14;35028:47;34911:171;:::o;35088:366::-;35230:3;35251:67;35315:2;35310:3;35251:67;:::i;:::-;35244:74;;35327:93;35416:3;35327:93;:::i;:::-;35445:2;35440:3;35436:12;35429:19;;35088:366;;;:::o;35460:419::-;35626:4;35664:2;35653:9;35649:18;35641:26;;35713:9;35707:4;35703:20;35699:1;35688:9;35684:17;35677:47;35741:131;35867:4;35741:131;:::i;:::-;35733:139;;35460:419;;;:::o;35885:781::-;35979:6;35987;35995;36003;36052:3;36040:9;36031:7;36027:23;36023:33;36020:120;;;36059:79;;:::i;:::-;36020:120;36179:1;36204:53;36249:7;36240:6;36229:9;36225:22;36204:53;:::i;:::-;36194:63;;36150:117;36306:2;36332:53;36377:7;36368:6;36357:9;36353:22;36332:53;:::i;:::-;36322:63;;36277:118;36434:2;36460:53;36505:7;36496:6;36485:9;36481:22;36460:53;:::i;:::-;36450:63;;36405:118;36562:2;36588:61;36641:7;36632:6;36621:9;36617:22;36588:61;:::i;:::-;36578:71;;36533:126;35885:781;;;;;;;:::o;36672:180::-;36720:77;36717:1;36710:88;36817:4;36814:1;36807:15;36841:4;36838:1;36831:15;36858:180;36906:77;36903:1;36896:88;37003:4;37000:1;36993:15;37027:4;37024:1;37017:15;37044:442;37193:4;37231:2;37220:9;37216:18;37208:26;;37244:71;37312:1;37301:9;37297:17;37288:6;37244:71;:::i;:::-;37325:72;37393:2;37382:9;37378:18;37369:6;37325:72;:::i;:::-;37407;37475:2;37464:9;37460:18;37451:6;37407:72;:::i;:::-;37044:442;;;;;;:::o;37492:::-;37641:4;37679:2;37668:9;37664:18;37656:26;;37692:71;37760:1;37749:9;37745:17;37736:6;37692:71;:::i;:::-;37773:72;37841:2;37830:9;37826:18;37817:6;37773:72;:::i;:::-;37855;37923:2;37912:9;37908:18;37899:6;37855:72;:::i;:::-;37492:442;;;;;;:::o;37940:117::-;38049:1;38046;38039:12;38063:117;38172:1;38169;38162:12;38186:117;38295:1;38292;38285:12;38309:724;38386:4;38392:6;38448:11;38435:25;38548:1;38542:4;38538:12;38527:8;38511:14;38507:29;38503:48;38483:18;38479:73;38469:168;;38556:79;;:::i;:::-;38469:168;38668:18;38658:8;38654:33;38646:41;;38720:4;38707:18;38697:28;;38748:18;38740:6;38737:30;38734:117;;;38770:79;;:::i;:::-;38734:117;38878:2;38872:4;38868:13;38860:21;;38935:4;38927:6;38923:17;38907:14;38903:38;38897:4;38893:49;38890:136;;;38945:79;;:::i;:::-;38890:136;38399:634;38309:724;;;;;:::o;39039:191::-;39079:3;39098:20;39116:1;39098:20;:::i;:::-;39093:25;;39132:20;39150:1;39132:20;:::i;:::-;39127:25;;39175:1;39172;39168:9;39161:16;;39196:3;39193:1;39190:10;39187:36;;;39203:18;;:::i;:::-;39187:36;39039:191;;;;:::o;39236:185::-;39276:1;39293:20;39311:1;39293:20;:::i;:::-;39288:25;;39327:20;39345:1;39327:20;:::i;:::-;39322:25;;39366:1;39356:35;;39371:18;;:::i;:::-;39356:35;39413:1;39410;39406:9;39401:14;;39236:185;;;;:::o;39427:553::-;39604:4;39642:3;39631:9;39627:19;39619:27;;39656:71;39724:1;39713:9;39709:17;39700:6;39656:71;:::i;:::-;39737:72;39805:2;39794:9;39790:18;39781:6;39737:72;:::i;:::-;39819;39887:2;39876:9;39872:18;39863:6;39819:72;:::i;:::-;39901;39969:2;39958:9;39954:18;39945:6;39901:72;:::i;:::-;39427:553;;;;;;;:::o;39986:117::-;40095:1;40092;40085:12;40109:117;40218:1;40215;40208:12;40232:469;40337:9;40348;40386:8;40374:10;40371:24;40368:111;;;40398:79;;:::i;:::-;40368:111;40504:6;40494:8;40491:20;40488:107;;;40514:79;;:::i;:::-;40488:107;40645:1;40633:10;40629:18;40621:6;40617:31;40604:44;;40684:10;40674:8;40670:25;40657:38;;40232:469;;;;;;;:::o;40707:470::-;40773:6;40781;40830:2;40818:9;40809:7;40805:23;40801:32;40798:119;;;40836:79;;:::i;:::-;40798:119;40956:1;40981:52;41025:7;41016:6;41005:9;41001:22;40981:52;:::i;:::-;40971:62;;40927:116;41082:2;41108:52;41152:7;41143:6;41132:9;41128:22;41108:52;:::i;:::-;41098:62;;41053:117;40707:470;;;;;:::o;41183:105::-;41219:7;41259:22;41252:5;41248:34;41237:45;;41183:105;;;:::o;41294:120::-;41366:23;41383:5;41366:23;:::i;:::-;41359:5;41356:34;41346:62;;41404:1;41401;41394:12;41346:62;41294:120;:::o;41420:141::-;41476:5;41507:6;41501:13;41492:22;;41523:32;41549:5;41523:32;:::i;:::-;41420:141;;;;:::o;41567:76::-;41603:7;41632:5;41621:16;;41567:76;;;:::o;41649:120::-;41721:23;41738:5;41721:23;:::i;:::-;41714:5;41711:34;41701:62;;41759:1;41756;41749:12;41701:62;41649:120;:::o;41775:141::-;41831:5;41862:6;41856:13;41847:22;;41878:32;41904:5;41878:32;:::i;:::-;41775:141;;;;:::o;41922:971::-;42025:6;42033;42041;42049;42057;42106:3;42094:9;42085:7;42081:23;42077:33;42074:120;;;42113:79;;:::i;:::-;42074:120;42233:1;42258:63;42313:7;42304:6;42293:9;42289:22;42258:63;:::i;:::-;42248:73;;42204:127;42370:2;42396:63;42451:7;42442:6;42431:9;42427:22;42396:63;:::i;:::-;42386:73;;42341:128;42508:2;42534:64;42590:7;42581:6;42570:9;42566:22;42534:64;:::i;:::-;42524:74;;42479:129;42647:2;42673:64;42729:7;42720:6;42709:9;42705:22;42673:64;:::i;:::-;42663:74;;42618:129;42786:3;42813:63;42868:7;42859:6;42848:9;42844:22;42813:63;:::i;:::-;42803:73;;42757:129;41922:971;;;;;;;;:::o;42899:181::-;43039:33;43035:1;43027:6;43023:14;43016:57;42899:181;:::o;43086:366::-;43228:3;43249:67;43313:2;43308:3;43249:67;:::i;:::-;43242:74;;43325:93;43414:3;43325:93;:::i;:::-;43443:2;43438:3;43434:12;43427:19;;43086:366;;;:::o;43458:419::-;43624:4;43662:2;43651:9;43647:18;43639:26;;43711:9;43705:4;43701:20;43697:1;43686:9;43682:17;43675:47;43739:131;43865:4;43739:131;:::i;:::-;43731:139;;43458:419;;;:::o;43883:172::-;44023:24;44019:1;44011:6;44007:14;44000:48;43883:172;:::o;44061:366::-;44203:3;44224:67;44288:2;44283:3;44224:67;:::i;:::-;44217:74;;44300:93;44389:3;44300:93;:::i;:::-;44418:2;44413:3;44409:12;44402:19;;44061:366;;;:::o;44433:419::-;44599:4;44637:2;44626:9;44622:18;44614:26;;44686:9;44680:4;44676:20;44672:1;44661:9;44657:17;44650:47;44714:131;44840:4;44714:131;:::i;:::-;44706:139;;44433:419;;;:::o;44858:174::-;44998:26;44994:1;44986:6;44982:14;44975:50;44858:174;:::o;45038:366::-;45180:3;45201:67;45265:2;45260:3;45201:67;:::i;:::-;45194:74;;45277:93;45366:3;45277:93;:::i;:::-;45395:2;45390:3;45386:12;45379:19;;45038:366;;;:::o;45410:419::-;45576:4;45614:2;45603:9;45599:18;45591:26;;45663:9;45657:4;45653:20;45649:1;45638:9;45634:17;45627:47;45691:131;45817:4;45691:131;:::i;:::-;45683:139;;45410:419;;;:::o;45835:181::-;45975:33;45971:1;45963:6;45959:14;45952:57;45835:181;:::o;46022:366::-;46164:3;46185:67;46249:2;46244:3;46185:67;:::i;:::-;46178:74;;46261:93;46350:3;46261:93;:::i;:::-;46379:2;46374:3;46370:12;46363:19;;46022:366;;;:::o;46394:419::-;46560:4;46598:2;46587:9;46583:18;46575:26;;46647:9;46641:4;46637:20;46633:1;46622:9;46618:17;46611:47;46675:131;46801:4;46675:131;:::i;:::-;46667:139;;46394:419;;;:::o;46819:221::-;46959:34;46955:1;46947:6;46943:14;46936:58;47028:4;47023:2;47015:6;47011:15;47004:29;46819:221;:::o;47046:366::-;47188:3;47209:67;47273:2;47268:3;47209:67;:::i;:::-;47202:74;;47285:93;47374:3;47285:93;:::i;:::-;47403:2;47398:3;47394:12;47387:19;;47046:366;;;:::o;47418:419::-;47584:4;47622:2;47611:9;47607:18;47599:26;;47671:9;47665:4;47661:20;47657:1;47646:9;47642:17;47635:47;47699:131;47825:4;47699:131;:::i;:::-;47691:139;;47418:419;;;:::o;47843:86::-;47878:7;47918:4;47911:5;47907:16;47896:27;;47843:86;;;:::o;47935:112::-;48018:22;48034:5;48018:22;:::i;:::-;48013:3;48006:35;47935:112;;:::o;48053:545::-;48226:4;48264:3;48253:9;48249:19;48241:27;;48278:71;48346:1;48335:9;48331:17;48322:6;48278:71;:::i;:::-;48359:68;48423:2;48412:9;48408:18;48399:6;48359:68;:::i;:::-;48437:72;48505:2;48494:9;48490:18;48481:6;48437:72;:::i;:::-;48519;48587:2;48576:9;48572:18;48563:6;48519:72;:::i;:::-;48053:545;;;;;;;:::o
Swarm Source
ipfs://58ccc6f71b1a510115f9dc3c96fc21547e278904a70cf3b62c2a4d23d2f792f4
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.