Source Code
Overview
ETH Balance
2.5179780597674514 ETH
Token Holdings
More Info
ContractCreator
Multi Chain
Multichain Addresses
3 addresses found via
Latest 25 from a total of 151 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Deposit To | 8619234 | 203 days 1 hr ago | IN | 0.01 ETH | 0.00353443 | ||||
Handle Ops | 8461654 | 230 days 5 hrs ago | IN | 0 ETH | 0.00005424 | ||||
Handle Ops | 8403600 | 240 days 2 hrs ago | IN | 0 ETH | 0 | ||||
Handle Ops | 8403575 | 240 days 2 hrs ago | IN | 0 ETH | 0 | ||||
Handle Ops | 8402757 | 240 days 5 hrs ago | IN | 0 ETH | 0 | ||||
Handle Ops | 8402600 | 240 days 6 hrs ago | IN | 0 ETH | 0.00013904 | ||||
Handle Ops | 8402031 | 240 days 8 hrs ago | IN | 0 ETH | 0.00059094 | ||||
Handle Ops | 8386404 | 243 days 9 mins ago | IN | 0 ETH | 0.00254197 | ||||
Handle Ops | 8386358 | 243 days 20 mins ago | IN | 0 ETH | 0.00322495 | ||||
Handle Ops | 8386272 | 243 days 41 mins ago | IN | 0 ETH | 0.0050284 | ||||
Handle Ops | 8386264 | 243 days 43 mins ago | IN | 0 ETH | 0.00374598 | ||||
Handle Ops | 8386247 | 243 days 47 mins ago | IN | 0 ETH | 0.00389923 | ||||
Handle Ops | 8386209 | 243 days 57 mins ago | IN | 0 ETH | 0.00444806 | ||||
Handle Ops | 8386187 | 243 days 1 hr ago | IN | 0 ETH | 0.00492408 | ||||
Handle Ops | 8386168 | 243 days 1 hr ago | IN | 0 ETH | 0.00394767 | ||||
Handle Ops | 8386116 | 243 days 1 hr ago | IN | 0 ETH | 0.00581639 | ||||
Handle Ops | 8386112 | 243 days 1 hr ago | IN | 0 ETH | 0.00477312 | ||||
Handle Ops | 8385751 | 243 days 2 hrs ago | IN | 0 ETH | 0.0003703 | ||||
Handle Ops | 8385723 | 243 days 3 hrs ago | IN | 0 ETH | 0.0003813 | ||||
Handle Ops | 8385634 | 243 days 3 hrs ago | IN | 0 ETH | 0.00289124 | ||||
Transfer | 8367418 | 246 days 5 hrs ago | IN | 0.1 ETH | 0.00006765 | ||||
Handle Ops | 8367157 | 246 days 6 hrs ago | IN | 0 ETH | 0.00013617 | ||||
Handle Ops | 8367146 | 246 days 6 hrs ago | IN | 0 ETH | 0.00013567 | ||||
Handle Ops | 8367121 | 246 days 6 hrs ago | IN | 0 ETH | 0.00013561 | ||||
Handle Ops | 8367111 | 246 days 6 hrs ago | IN | 0 ETH | 0.00013561 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
8461654 | 230 days 5 hrs ago | 0.00006318 ETH | ||||
8461654 | 230 days 5 hrs ago | 0 ETH | ||||
8461654 | 230 days 5 hrs ago | 0 ETH | ||||
8461654 | 230 days 5 hrs ago | 0.00011765 ETH | ||||
8461654 | 230 days 5 hrs ago | 0 ETH | ||||
8403600 | 240 days 2 hrs ago | 0 ETH | ||||
8403600 | 240 days 2 hrs ago | 0 ETH | ||||
8403600 | 240 days 2 hrs ago | 0 ETH | ||||
8403600 | 240 days 2 hrs ago | 0.00000001 ETH | ||||
8403600 | 240 days 2 hrs ago | 0 ETH | ||||
8403575 | 240 days 2 hrs ago | 0 ETH | ||||
8403575 | 240 days 2 hrs ago | 0 ETH | ||||
8403575 | 240 days 2 hrs ago | 0 ETH | ||||
8403575 | 240 days 2 hrs ago | 0.00000011 ETH | ||||
8403575 | 240 days 2 hrs ago | 0 ETH | ||||
8403575 | 240 days 2 hrs ago | 0 ETH | ||||
8402757 | 240 days 5 hrs ago | 0 ETH | ||||
8402757 | 240 days 5 hrs ago | 0 ETH | ||||
8402757 | 240 days 5 hrs ago | 0 ETH | ||||
8402757 | 240 days 5 hrs ago | 0 ETH | ||||
8402600 | 240 days 6 hrs ago | 0.00014636 ETH | ||||
8402600 | 240 days 6 hrs ago | 0 ETH | ||||
8402600 | 240 days 6 hrs ago | 0 ETH | ||||
8402600 | 240 days 6 hrs ago | 0.00015249 ETH | ||||
8402600 | 240 days 6 hrs ago | 0 ETH |
Loading...
Loading
Contract Name:
EntryPoint
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
/** ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation. ** Only one instance required on each chain. **/ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; /* solhint-disable avoid-low-level-calls */ /* solhint-disable no-inline-assembly */ import "../interfaces/IAccount.sol"; import "../interfaces/IPaymaster.sol"; import "../interfaces/IAggregatedAccount.sol"; import "../interfaces/IEntryPoint.sol"; import "./StakeManager.sol"; import "./SenderCreator.sol"; contract EntryPoint is IEntryPoint, StakeManager { using UserOperationLib for UserOperation; SenderCreator private immutable senderCreator = new SenderCreator(); // internal value used during simulation: need to query aggregator. address private constant SIMULATE_FIND_AGGREGATOR = address(1); /** * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value * in case of signature failure, instead of revert. */ uint256 public constant SIG_VALIDATION_FAILED = 1; /** * compensate the caller's beneficiary address with the collected fees of all UserOperations. * @param beneficiary the address to receive the fees * @param amount amount to transfer. */ function _compensate(address payable beneficiary, uint256 amount) internal { require(beneficiary != address(0), "AA90 invalid beneficiary"); (bool success,) = beneficiary.call{value : amount}(""); require(success, "AA91 failed send to beneficiary"); } /** * execute a user op * @param opIndex into into the opInfo array * @param userOp the userOp to execute * @param opInfo the opInfo filled by validatePrepayment for this userOp. * @return collected the total amount this userOp paid. */ function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) { uint256 preGas = gasleft(); bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset); try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) { collected = _actualGasCost; } catch { uint256 actualGas = preGas - gasleft() + opInfo.preOpGas; collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas); } } /** * Execute a batch of UserOperation. * no signature aggregator is used. * if any account requires an aggregator (that is, it returned an "actualAggregator" 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) public { uint256 opslen = ops.length; UserOpInfo[] memory opInfos = new UserOpInfo[](opslen); unchecked { for (uint256 i = 0; i < opslen; i++) { UserOpInfo memory opInfo = opInfos[i]; (uint256 deadline, uint256 paymasterDeadline,) = _validatePrepayment(i, ops[i], opInfo, address(0)); _validateDeadline(i, opInfo, deadline, paymasterDeadline); } uint256 collected = 0; for (uint256 i = 0; i < opslen; i++) { collected += _executeUserOp(i, ops[i], opInfos[i]); } _compensate(beneficiary, collected); } //unchecked } /** * 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 ) public { uint256 opasLen = opsPerAggregator.length; uint256 totalOps = 0; for (uint256 i = 0; i < opasLen; i++) { totalOps += opsPerAggregator[i].userOps.length; } UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps); uint256 opIndex = 0; for (uint256 a = 0; a < opasLen; a++) { UserOpsPerAggregator calldata opa = opsPerAggregator[a]; UserOperation[] calldata ops = opa.userOps; IAggregator aggregator = opa.aggregator; uint256 opslen = ops.length; for (uint256 i = 0; i < opslen; i++) { UserOpInfo memory opInfo = opInfos[opIndex]; (uint256 deadline, uint256 paymasterDeadline,) = _validatePrepayment(opIndex, ops[i], opInfo, address(aggregator)); _validateDeadline(i, opInfo, deadline, paymasterDeadline); opIndex++; } if (address(aggregator) != address(0)) { // solhint-disable-next-line no-empty-blocks try aggregator.validateSignatures(ops, opa.signature) {} catch { revert SignatureValidationFailed(address(aggregator)); } } } uint256 collected = 0; opIndex = 0; for (uint256 a = 0; a < opasLen; a++) { UserOpsPerAggregator calldata opa = opsPerAggregator[a]; emit SignatureAggregatorChanged(address(opa.aggregator)); UserOperation[] calldata ops = opa.userOps; uint256 opslen = ops.length; for (uint256 i = 0; i < opslen; i++) { collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]); opIndex++; } } emit SignatureAggregatorChanged(address(0)); _compensate(beneficiary, collected); } function simulateHandleOp(UserOperation calldata op) external override { UserOpInfo memory opInfo; (uint256 deadline, uint256 paymasterDeadline,) = _validatePrepayment(0, op, opInfo, SIMULATE_FIND_AGGREGATOR); //ignore signature check failure if (deadline == SIG_VALIDATION_FAILED) { deadline = 0; } if (paymasterDeadline == SIG_VALIDATION_FAILED) { paymasterDeadline = 0; } _validateDeadline(0, opInfo, deadline, paymasterDeadline); numberMarker(); uint256 paid = _executeUserOp(0, op, opInfo); revert ExecutionResult(opInfo.preOpGas, paid, deadline, paymasterDeadline); } //a memory copy of UserOp fields (except that dynamic byte arrays: callData, initCode and signature struct MemoryUserOp { address sender; uint256 nonce; uint256 callGasLimit; uint256 verificationGasLimit; uint256 preVerificationGas; address paymaster; uint256 maxFeePerGas; uint256 maxPriorityFeePerGas; } struct UserOpInfo { MemoryUserOp mUserOp; bytes32 userOpHash; uint256 prefund; uint256 contextOffset; uint256 preOpGas; } /** * inner function to handle a UserOperation. * Must be declared "external" to open a call context, but it can only be called by handleOps. */ function innerHandleOp(bytes calldata callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) { uint256 preGas = gasleft(); require(msg.sender == address(this), "AA92 internal call only"); MemoryUserOp memory mUserOp = opInfo.mUserOp; IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded; if (callData.length > 0) { (bool success,bytes memory result) = address(mUserOp.sender).call{gas : mUserOp.callGasLimit}(callData); if (!success) { if (result.length > 0) { emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result); } mode = IPaymaster.PostOpMode.opReverted; } } unchecked { uint256 actualGas = preGas - gasleft() + opInfo.preOpGas; //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp) return _handlePostOp(0, mode, opInfo, context, actualGas); } } /** * 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) public view returns (bytes32) { return keccak256(abi.encode(userOp.hash(), address(this), block.chainid)); } /** * copy general fields from userOp into the memory opInfo structure. */ function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure { mUserOp.sender = userOp.sender; mUserOp.nonce = userOp.nonce; mUserOp.callGasLimit = userOp.callGasLimit; mUserOp.verificationGasLimit = userOp.verificationGasLimit; mUserOp.preVerificationGas = userOp.preVerificationGas; mUserOp.maxFeePerGas = userOp.maxFeePerGas; mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; bytes calldata paymasterAndData = userOp.paymasterAndData; if (paymasterAndData.length > 0) { require(paymasterAndData.length >= 20, "AA93 invalid paymasterAndData"); mUserOp.paymaster = address(bytes20(paymasterAndData[: 20])); } else { mUserOp.paymaster = address(0); } } /** * 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 { UserOpInfo memory outOpInfo; (uint256 deadline, uint256 paymasterDeadline, address aggregator) = _validatePrepayment(0, userOp, outOpInfo, SIMULATE_FIND_AGGREGATOR); StakeInfo memory paymasterInfo = getStakeInfo(outOpInfo.mUserOp.paymaster); StakeInfo memory senderInfo = getStakeInfo(outOpInfo.mUserOp.sender); bytes calldata initCode = userOp.initCode; address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0); StakeInfo memory factoryInfo = getStakeInfo(factory); ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund, deadline, paymasterDeadline, getMemoryBytesFromOffset(outOpInfo.contextOffset)); if (aggregator != address(0)) { AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, getStakeInfo(aggregator)); revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo); } revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo); } function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal view returns (uint256 requiredPrefund) { unchecked { //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call. // our security model might call postOp eventually twice uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1; uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas; // TODO: copy logic of gasPrice? requiredPrefund = requiredGas * getUserOpGasPrice(mUserOp); } } // create the sender's contract if needed. function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal { if (initCode.length != 0) { address sender = opInfo.mUserOp.sender; if (sender.code.length != 0) revert FailedOp(opIndex, address(0), "AA10 sender already constructed"); address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode); if (sender1 == address(0)) revert FailedOp(opIndex, address(0), "AA13 initCode failed or OOG"); if (sender1 != sender) revert FailedOp(opIndex, address(0), "AA14 initCode must return sender"); if (sender1.code.length == 0) revert FailedOp(opIndex, address(0), "AA15 initCode must create sender"); address factory = address(bytes20(initCode[0 : 20])); emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster); } } /** * 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 calldata initCode) public { revert SenderAddressResult(senderCreator.createSender(initCode)); } /** * call account.validateUserOp. * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund. * decrement account's deposit if needed */ function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, address aggregator, uint256 requiredPrefund) internal returns (uint256 gasUsedByValidateAccountPrepayment, address actualAggregator, uint256 deadline) { unchecked { uint256 preGas = gasleft(); MemoryUserOp memory mUserOp = opInfo.mUserOp; address sender = mUserOp.sender; _createSenderIfNeeded(opIndex, opInfo, op.initCode); if (aggregator == SIMULATE_FIND_AGGREGATOR) { numberMarker(); if (sender.code.length == 0) { // it would revert anyway. but give a meaningful message revert FailedOp(0, address(0), "AA20 account not deployed"); } if (mUserOp.paymaster != address(0) && mUserOp.paymaster.code.length == 0) { // it would revert anyway. but give a meaningful message revert FailedOp(0, address(0), "AA30 paymaster not deployed"); } // during simulation, we don't use given aggregator, // but query the account for its aggregator try IAggregatedAccount(sender).getAggregator() returns (address userOpAggregator) { aggregator = actualAggregator = userOpAggregator; } catch { aggregator = actualAggregator = address(0); } } uint256 missingAccountFunds = 0; address paymaster = mUserOp.paymaster; if (paymaster == address(0)) { uint256 bal = balanceOf(sender); missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal; } try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, aggregator, missingAccountFunds) returns (uint256 _deadline) { deadline = _deadline; } catch Error(string memory revertReason) { revert FailedOp(opIndex, address(0), revertReason); } catch { revert FailedOp(opIndex, address(0), "AA23 reverted (or OOG)"); } if (paymaster == address(0)) { DepositInfo storage senderInfo = deposits[sender]; uint256 deposit = senderInfo.deposit; if (requiredPrefund > deposit) { revert FailedOp(opIndex, address(0), "AA21 didn't pay prefund"); } senderInfo.deposit = uint112(deposit - requiredPrefund); } gasUsedByValidateAccountPrepayment = preGas - gasleft(); } } /** * in case the request has a paymaster: * validate paymaster is staked and has enough deposit. * call paymaster.validatePaymasterUserOp. * revert with proper FailedOp in case paymaster reverts. * decrement paymaster's deposit */ function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment) internal returns (bytes memory context, uint256 deadline) { unchecked { MemoryUserOp memory mUserOp = opInfo.mUserOp; uint256 verificationGasLimit = mUserOp.verificationGasLimit; require(verificationGasLimit > gasUsedByValidateAccountPrepayment, "AA41 too little verificationGas"); uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment; address paymaster = mUserOp.paymaster; DepositInfo storage paymasterInfo = deposits[paymaster]; uint256 deposit = paymasterInfo.deposit; if (deposit < requiredPreFund) { revert FailedOp(opIndex, paymaster, "AA31 paymaster deposit too low"); } paymasterInfo.deposit = uint112(deposit - requiredPreFund); try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _deadline){ context = _context; deadline = _deadline; } catch Error(string memory revertReason) { revert FailedOp(opIndex, paymaster, revertReason); } catch { revert FailedOp(opIndex, paymaster, "AA33 reverted (or OOG)"); } } } /** * revert if either account deadline or paymaster deadline is expired */ function _validateDeadline(uint256 opIndex, UserOpInfo memory opInfo, uint256 deadline, uint256 paymasterDeadline) internal view { //we want to treat "zero" as "maxint", so we subtract one, ignoring underflow unchecked { // solhint-disable-next-line not-rely-on-time if (deadline != 0 && deadline < block.timestamp) { if (deadline == SIG_VALIDATION_FAILED) { revert FailedOp(opIndex, address(0), "AA24 signature error"); } else { revert FailedOp(opIndex, address(0), "AA22 expired"); } } // solhint-disable-next-line not-rely-on-time if (paymasterDeadline != 0 && paymasterDeadline < block.timestamp) { address paymaster = opInfo.mUserOp.paymaster; if (paymasterDeadline == SIG_VALIDATION_FAILED) { revert FailedOp(opIndex, paymaster, "AA34 signature error"); } else { revert FailedOp(opIndex, paymaster, "AA32 paymaster expired"); } } } } /** * validate account and paymaster (if defined). * also make sure total validation doesn't exceed verificationGasLimit * this method is called off-chain (simulateValidation()) and on-chain (from handleOps) * @param opIndex the index of this userOp into the "opInfos" array * @param userOp the userOp to validate */ function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo, address aggregator) private returns (uint256 deadline, uint256 paymasterDeadline, address actualAggregator) { uint256 preGas = gasleft(); MemoryUserOp memory mUserOp = outOpInfo.mUserOp; _copyUserOpToMemory(userOp, mUserOp); outOpInfo.userOpHash = getUserOpHash(userOp); // validate all numeric values in userOp are well below 128 bit, so they can safely be added // and multiplied without causing overflow uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit | userOp.maxFeePerGas | userOp.maxPriorityFeePerGas; require(maxGasValues <= type(uint120).max, "AA94 gas values overflow"); uint256 gasUsedByValidateAccountPrepayment; (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp); (gasUsedByValidateAccountPrepayment, actualAggregator, deadline) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, aggregator, requiredPreFund); //a "marker" where account opcode validation is done and paymaster opcode validation is about to start // (used only by off-chain simulateValidation) numberMarker(); bytes memory context; if (mUserOp.paymaster != address(0)) { (context, paymasterDeadline) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment); } unchecked { uint256 gasUsed = preGas - gasleft(); if (userOp.verificationGasLimit < gasUsed) { revert FailedOp(opIndex, mUserOp.paymaster, "AA40 over verificationGasLimit"); } outOpInfo.prefund = requiredPreFund; outOpInfo.contextOffset = getOffsetOfMemoryBytes(context); outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas; } } /** * process post-operation. * called just after the callData is executed. * if a paymaster is defined and its validation returned a non-empty context, its postOp is called. * the excess amount is refunded to the account (or paymaster - if it is was used in the request) * @param opIndex index in the batch * @param mode - whether is called from innerHandleOp, or outside (postOpReverted) * @param opInfo userOp fields and info collected during validation * @param context the context returned in validatePaymasterUserOp * @param actualGas the gas used so far by this user operation */ function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) { uint256 preGas = gasleft(); unchecked { address refundAddress; MemoryUserOp memory mUserOp = opInfo.mUserOp; uint256 gasPrice = getUserOpGasPrice(mUserOp); address paymaster = mUserOp.paymaster; if (paymaster == address(0)) { refundAddress = mUserOp.sender; } else { refundAddress = paymaster; if (context.length > 0) { actualGasCost = actualGas * gasPrice; if (mode != IPaymaster.PostOpMode.postOpReverted) { IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost); } else { // solhint-disable-next-line no-empty-blocks try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {} catch Error(string memory reason) { revert FailedOp(opIndex, paymaster, reason); } catch { revert FailedOp(opIndex, paymaster, "A50 postOp revert"); } } } } actualGas += preGas - gasleft(); actualGasCost = actualGas * gasPrice; if (opInfo.prefund < actualGasCost) { revert FailedOp(opIndex, paymaster, "A51 prefund below actualGasCost"); } uint256 refund = opInfo.prefund - actualGasCost; internalIncrementDeposit(refundAddress, refund); bool success = mode == IPaymaster.PostOpMode.opSucceeded; emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas); } // unchecked } /** * the gas price this UserOp agrees to pay. * relayer/block builder might submit the TX with higher priorityFee, but the user should not */ function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) { unchecked { uint256 maxFeePerGas = mUserOp.maxFeePerGas; uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas; if (maxFeePerGas == maxPriorityFeePerGas) { //legacy mode (for networks that don't support basefee opcode) return maxFeePerGas; } return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee); } } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) { assembly {offset := data} } function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) { assembly {data := offset} } //place the NUMBER opcode in the code. // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the // account and paymaster. function numberMarker() internal view { assembly {mstore(0, number())} } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; /** * helper contract for EntryPoint, to call userOp.initCode from a "neutral" address, * which is explicitly not the entryPoint itself. */ contract SenderCreator { /** * call the "initCode" factory to create and return the sender account address * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata * @return sender the returned address of the created account, or zero address on failure. */ function createSender(bytes calldata initCode) external returns (address sender) { address initAddress = address(bytes20(initCode[0 : 20])); bytes memory initCallData = initCode[20 :]; bool success; /* solhint-disable no-inline-assembly */ assembly { success := call(gas(), initAddress, 0, add(initCallData, 0x20), mload(initCallData), 0, 32) sender := mload(0) } if (!success) { sender = address(0); } } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.12; import "../interfaces/IStakeManager.sol"; /* solhint-disable avoid-low-level-calls */ /* solhint-disable not-rely-on-time */ /** * 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 a paymaster. */ abstract contract StakeManager is IStakeManager { /// maps paymaster to their deposits and stakes mapping(address => DepositInfo) public deposits; function getDepositInfo(address account) public view returns (DepositInfo memory info) { return deposits[account]; } // internal method to return just the stake info function getStakeInfo(address addr) internal view returns (StakeInfo memory info) { DepositInfo storage depositInfo = deposits[addr]; info.stake = depositInfo.stake; info.unstakeDelaySec = depositInfo.unstakeDelaySec; } /// return the deposit (for gas payment) of the account function balanceOf(address account) public view returns (uint256) { return deposits[account].deposit; } receive() external payable { depositTo(msg.sender); } function internalIncrementDeposit(address account, uint256 amount) internal { DepositInfo storage info = deposits[account]; uint256 newAmount = info.deposit + amount; require(newAmount <= type(uint112).max, "deposit overflow"); info.deposit = uint112(newAmount); } /** * add to the deposit of the given account */ function depositTo(address account) public payable { internalIncrementDeposit(account, msg.value); DepositInfo storage info = deposits[account]; emit Deposited(account, info.deposit); } /** * 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) public payable { DepositInfo storage info = deposits[msg.sender]; require(_unstakeDelaySec > 0, "must specify unstake delay"); require(_unstakeDelaySec >= info.unstakeDelaySec, "cannot decrease unstake time"); uint256 stake = info.stake + msg.value; require(stake > 0, "no stake specified"); require(stake < type(uint112).max, "stake overflow"); deposits[msg.sender] = DepositInfo( info.deposit, true, uint112(stake), _unstakeDelaySec, 0 ); emit StakeLocked(msg.sender, stake, _unstakeDelaySec); } /** * attempt to unlock the stake. * the value can be withdrawn (using withdrawStake) after the unstake delay. */ function unlockStake() external { DepositInfo storage info = deposits[msg.sender]; require(info.unstakeDelaySec != 0, "not staked"); require(info.staked, "already unstaking"); uint64 withdrawTime = uint64(block.timestamp) + info.unstakeDelaySec; info.withdrawTime = withdrawTime; info.staked = false; emit StakeUnlocked(msg.sender, withdrawTime); } /** * 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 { DepositInfo storage info = deposits[msg.sender]; uint256 stake = info.stake; require(stake > 0, "No stake to withdraw"); require(info.withdrawTime > 0, "must call unlockStake() first"); require(info.withdrawTime <= block.timestamp, "Stake withdrawal is not due"); info.unstakeDelaySec = 0; info.withdrawTime = 0; info.stake = 0; emit StakeWithdrawn(msg.sender, withdrawAddress, stake); (bool success,) = withdrawAddress.call{value : stake}(""); require(success, "failed to withdraw stake"); } /** * 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 { DepositInfo storage info = deposits[msg.sender]; require(withdrawAmount <= info.deposit, "Withdraw amount too large"); info.deposit = uint112(info.deposit - withdrawAmount); emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount); (bool success,) = withdrawAddress.call{value : withdrawAmount}(""); require(success, "failed to withdraw"); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; import "./UserOperation.sol"; interface IAccount { /** * Validate user's signature and nonce * the entryPoint will make the call to the recipient only if this validation call returns successfully. * signature failure should be reported by returning SIG_VALIDATION_FAILED (1). * This allows making a "simulation call" without a valid signature * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure. * * @dev Must validate caller is the entryPoint. * Must validate the signature and nonce * @param userOp the operation that is about to be executed. * @param userOpHash hash of the user's request data. can be used as the basis for signature. * @param aggregator the aggregator used to validate the signature. NULL for non-aggregated signature accounts. * @param missingAccountFunds missing funds on the account's deposit in the entrypoint. * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call. * The excess is left as a deposit in the entrypoint, for future calls. * can be withdrawn anytime using "entryPoint.withdrawTo()" * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero. * @return deadline the last block timestamp this operation is valid, or zero if it is valid indefinitely. * signature failure is returned as SIG_VALIDATION_FAILED value (1) * Note that the validation code cannot use block.timestamp (or block.number) directly. */ function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, address aggregator, uint256 missingAccountFunds) external returns (uint256 deadline); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; import "./UserOperation.sol"; import "./IAccount.sol"; import "./IAggregator.sol"; /** * Aggregated account, that support IAggregator. * - the validateUserOp will be called only after the aggregator validated this account (with all other accounts of this aggregator). * - the validateUserOp MUST valiate the aggregator parameter, and MAY ignore the userOp.signature field. */ interface IAggregatedAccount is IAccount { /** * return the address of the signature aggregator the account supports. */ function getAggregator() external view returns (address); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; 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 return 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 aggregatesSignature the aggregated signature */ function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatesSignature); }
/** ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation. ** Only one instance required on each chain. **/ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; /* solhint-disable avoid-low-level-calls */ /* solhint-disable no-inline-assembly */ /* solhint-disable reason-string */ import "./UserOperation.sol"; import "./IStakeManager.sol"; import "./IAggregator.sol"; interface IEntryPoint is IStakeManager { /*** * 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 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) * @param success - true if the sender transaction succeeded, false if reverted. */ 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); /** * signature aggregator used by the following UserOperationEvents within this bundle. */ event SignatureAggregatorChanged(address 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 paymaster - if paymaster.validatePaymasterUserOp fails, this will be the paymaster's address. if validateUserOp failed, * this value will be zero (since it failed before accessing the paymaster) * @param reason - revert reason * Should be caught in off-chain handleOps simulation and not happen on-chain. * Useful for mitigating DoS attempts against batchers or for troubleshooting of account/paymaster reverts. */ error FailedOp(uint256 opIndex, address paymaster, string reason); /** * error case when a signature aggregator fails to verify the aggregated signature it had created. */ error SignatureValidationFailed(address aggregator); //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 "actualAggregator" 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; /** * Successful result from simulateValidation. * @param returnInfo gas and deadlines returned values * @param senderInfo stake information about the sender * @param factoryInfo stake information about the factor (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 deadlines returned values * @param senderInfo stake information about the sender * @param factoryInfo stake information about the factor (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); /** * gas and deadlines returned during simulation * @param preOpGas the gas used for validation (including preValidationGas) * @param prefund the required prefund for this operation * @param deadline validateUserOp's deadline (or SIG_VALIDATION_FAILED for signature failure) * @param paymasterDeadline validatePaymasterUserOp's deadline (or SIG_VALIDATION_FAILED for signature failure) * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp) */ struct ReturnInfo { uint256 preOpGas; uint256 prefund; uint256 deadline; uint256 paymasterDeadline; bytes paymasterContext; } /** * returned aggregated signature info. * the aggregator returned by the account, and its current stake. */ struct AggregatorStakeInfo { address actualAggregator; 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; /** * return value of getSenderAddress */ error SenderAddressResult(address sender); /** * simulate full execution of a UserOperation (including both validation and target execution) * this method will always revert. it performs full validation of the UserOperation, but ignores * signature error. * 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. */ function simulateHandleOp(UserOperation calldata op) external; error ExecutionResult(uint256 preOpGas, uint256 paid, uint256 deadline, uint256 paymasterDeadline); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; 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 { /** * payment validation: check if paymaster agree 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 deadline the last block timestamp this operation is valid, or zero if it is valid indefinitely. * 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 deadline); /** * 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; 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 its a 2nd call, after user's op was deliberately reverted. } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.12; /** * 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 a paymaster. */ interface IStakeManager { event Deposited( address indexed account, uint256 totalDeposit ); event Withdrawn( address indexed account, address withdrawAddress, uint256 amount ); /// Emitted once a stake is scheduled for withdrawal event StakeLocked( address indexed account, uint256 totalStaked, uint256 withdrawTime ); /// 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 account's deposit * @param staked true if this account is staked as a paymaster * @param stake actual amount of ether staked for this paymaster. * @param unstakeDelaySec minimum delay to withdraw the stake. must be above the global unstakeDelaySec * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked * @dev sizes were chosen so that (deposit,staked) fit into one cell (used during handleOps) * and the rest fit into a 2nd cell. * 112 bit allows for 2^15 eth * 64 bit for full timestamp * 32 bit allow 150 years for unstake delay */ struct DepositInfo { uint112 deposit; bool staked; uint112 stake; uint32 unstakeDelaySec; uint64 withdrawTime; } //API struct used by getStakeInfo and simulateValidation struct StakeInfo { uint256 stake; uint256 unstakeDelaySec; } 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.12; /* solhint-disable no-inline-assembly */ /** * 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 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 hold 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; } library UserOperationLib { 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. function gasPrice(UserOperation calldata userOp) internal view 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 + block.basefee); } } function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) { //lighter signature scheme. must match UserOp.ts#packUserOp bytes calldata sig = userOp.signature; // copy directly the userOp from calldata up to (but not including) the signature. // this encoding depends on the ABI encoding of calldata, but is much lighter to copy // than referencing each field separately. assembly { let ofs := userOp let len := sub(sub(sig.offset, ofs), 32) ret := mload(0x40) mstore(0x40, add(ret, add(len, 32))) mstore(ret, len) calldatacopy(add(ret, 32), ofs, len) } } function hash(UserOperation calldata userOp) internal pure returns (bytes32) { return keccak256(pack(userOp)); } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } }
{ "optimizer": { "enabled": true, "runs": 1000000 }, "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
[{"inputs":[{"internalType":"uint256","name":"preOpGas","type":"uint256"},{"internalType":"uint256","name":"paid","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"paymasterDeadline","type":"uint256"}],"name":"ExecutionResult","type":"error"},{"inputs":[{"internalType":"uint256","name":"opIndex","type":"uint256"},{"internalType":"address","name":"paymaster","type":"address"},{"internalType":"string","name":"reason","type":"string"}],"name":"FailedOp","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"SenderAddressResult","type":"error"},{"inputs":[{"internalType":"address","name":"aggregator","type":"address"}],"name":"SignatureValidationFailed","type":"error"},{"inputs":[{"components":[{"internalType":"uint256","name":"preOpGas","type":"uint256"},{"internalType":"uint256","name":"prefund","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"paymasterDeadline","type":"uint256"},{"internalType":"bytes","name":"paymasterContext","type":"bytes"}],"internalType":"struct IEntryPoint.ReturnInfo","name":"returnInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"senderInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"factoryInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"paymasterInfo","type":"tuple"}],"name":"ValidationResult","type":"error"},{"inputs":[{"components":[{"internalType":"uint256","name":"preOpGas","type":"uint256"},{"internalType":"uint256","name":"prefund","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"paymasterDeadline","type":"uint256"},{"internalType":"bytes","name":"paymasterContext","type":"bytes"}],"internalType":"struct IEntryPoint.ReturnInfo","name":"returnInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"senderInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"factoryInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"paymasterInfo","type":"tuple"},{"components":[{"internalType":"address","name":"actualAggregator","type":"address"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"stakeInfo","type":"tuple"}],"internalType":"struct IEntryPoint.AggregatorStakeInfo","name":"aggregatorInfo","type":"tuple"}],"name":"ValidationResultWithAggregation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"factory","type":"address"},{"indexed":false,"internalType":"address","name":"paymaster","type":"address"}],"name":"AccountDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalDeposit","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"aggregator","type":"address"}],"name":"SignatureAggregatorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalStaked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withdrawTime","type":"uint256"}],"name":"StakeLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawTime","type":"uint256"}],"name":"StakeUnlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"withdrawAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"paymaster","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint256","name":"actualGasCost","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"actualGasUsed","type":"uint256"}],"name":"UserOperationEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"revertReason","type":"bytes"}],"name":"UserOperationRevertReason","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"withdrawAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"SIG_VALIDATION_FAILED","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":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"depositTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"deposits","outputs":[{"internalType":"uint112","name":"deposit","type":"uint112"},{"internalType":"bool","name":"staked","type":"bool"},{"internalType":"uint112","name":"stake","type":"uint112"},{"internalType":"uint32","name":"unstakeDelaySec","type":"uint32"},{"internalType":"uint64","name":"withdrawTime","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getDepositInfo","outputs":[{"components":[{"internalType":"uint112","name":"deposit","type":"uint112"},{"internalType":"bool","name":"staked","type":"bool"},{"internalType":"uint112","name":"stake","type":"uint112"},{"internalType":"uint32","name":"unstakeDelaySec","type":"uint32"},{"internalType":"uint64","name":"withdrawTime","type":"uint64"}],"internalType":"struct IStakeManager.DepositInfo","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"}],"name":"getSenderAddress","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"}],"name":"getUserOpHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"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":"userOps","type":"tuple[]"},{"internalType":"contract IAggregator","name":"aggregator","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IEntryPoint.UserOpsPerAggregator[]","name":"opsPerAggregator","type":"tuple[]"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"handleAggregatedOps","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":"ops","type":"tuple[]"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"handleOps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"callData","type":"bytes"},{"components":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"address","name":"paymaster","type":"address"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"}],"internalType":"struct EntryPoint.MemoryUserOp","name":"mUserOp","type":"tuple"},{"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"internalType":"uint256","name":"prefund","type":"uint256"},{"internalType":"uint256","name":"contextOffset","type":"uint256"},{"internalType":"uint256","name":"preOpGas","type":"uint256"}],"internalType":"struct EntryPoint.UserOpInfo","name":"opInfo","type":"tuple"},{"internalType":"bytes","name":"context","type":"bytes"}],"name":"innerHandleOp","outputs":[{"internalType":"uint256","name":"actualGasCost","type":"uint256"}],"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":"op","type":"tuple"}],"name":"simulateHandleOp","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"}],"name":"simulateValidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockStake","outputs":[],"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":"withdrawAmount","type":"uint256"}],"name":"withdrawTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a08060405234620000845761022c8181016001600160401b038111838210176200006e57829162005c0a833903906000f080156200006257608052604051615b8090816200008a823960805181818161101401528181613e4401526141610152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b61002161546e565b005b60003560e01c80630396cb60146101635780631d7327561461015a5780631fad948c14610151578063205c2878146101485780634b1d7cf51461013f5780635287ce121461013657806370a082311461012d5780638f41ec5a146101245780639b249f691461011b578063a619353114610112578063b760faf914610109578063bb9fe6bf14610100578063c2077116146100f7578063c23a5cea146100ee578063ee219423146100e55763fc7e286d0361000e576100e0611917565b61000e565b506100e0611774565b506100e06115d7565b506100e06112e8565b506100e0611164565b506100e0611125565b506100e0611104565b506100e0610f6c565b506100e0610f31565b506100e0610eac565b506100e0610d56565b506100e0610a2b565b506100e061088c565b506100e061063b565b506100e0610478565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085760043563ffffffff8116808203610308576103037fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102216101f13373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b916101fd8115156155d4565b61021a610211600185015463ffffffff1690565b63ffffffff1690565b1115615639565b54926102e56dffffffffffffffffffffffffffff946102a361024834888460781c16611efd565b9661025488151561569e565b61025f818910615703565b6102838161026b610406565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526102e03373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b615768565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b9181601f840112156103085782359167ffffffffffffffff8311610308576020838186019501011161030857565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761038757604052565b61038f61033b565b604052565b610100810190811067ffffffffffffffff82111761038757604052565b67ffffffffffffffff811161038757604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761038757604052565b604051906104138261036b565b565b604051906040820182811067ffffffffffffffff82111761038757604052565b73ffffffffffffffffffffffffffffffffffffffff81160361030857565b6024359061041382610435565b60c4359061041382610435565b359061041382610435565b5034610308576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085767ffffffffffffffff600435818111610308576104ca90369060040161030d565b367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc019291610180841261030857610100604051946105088661036b565b126103085760405161051981610394565b610521610453565b815260443560208201526064356040820152608435606082015260a435608082015261054b610460565b60a082015260e43560c08201526101043560e082015284526101243560208501526101443560408501526101643560608501526101843560808501526101a435928311610308576105bf936105a76105af94369060040161030d565b939092612444565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103085760043567ffffffffffffffff9283821161030857806023830112156103085781600401359384116103085760248460051b8301011161030857602401919060243561063881610435565b90565b50346103085761064a366105c3565b610655829392611a79565b60005b8481106106a7575060009283915b858310610677576100218585611bff565b90919360019061069d61068b878987611b38565b6106958886611b16565b519088611fdf565b0194019190610666565b6106b381839593611b16565b516106bf828785611b38565b6000915a8151926106d08482612ddc565b6106d98161256f565b6020840152608091828501519460609586820151179561071f6effffffffffffffffffffffffffffff60409889850151176101008701359060e088013517171115612a01565b61072882612e9e565b6107348188878d6130a3565b9991905061074143600052565b839460a0809101918d73ffffffffffffffffffffffffffffffffffffffff61077d855173ffffffffffffffffffffffffffffffffffffffff1690565b1661086f575b50505a870390880135106107c457509260c0926107bb9997959289979560019d9c9a01528601525a90039101350190820152846127a0565b01929092610658565b61086b6107e68d925173ffffffffffffffffffffffffffffffffffffffff1690565b92519283927efa072b000000000000000000000000000000000000000000000000000000008452600484019060a09273ffffffffffffffffffffffffffffffffffffffff91835216602082015260606040820152601e60608201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060808201520190565b0390fd5b610882939d508591929750898c916147d9565b9a9094388d610783565b50346103085760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610308576004356108c881610435565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff815416928383116109cd57848373ffffffffffffffffffffffffffffffffffffffff829593610970849661093761092487986109ca9c611ee8565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af16109c4611bcf565b50615ae5565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b503461030857610a3a366105c3565b6000805b838210610d2757610a4f9150611a79565b6000805b848110610b9957505060008093815b818110610aaa5761002186867f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d60405180610aa281906000602083019252565b0390a1611bff565b610b34610ab882848a6120e0565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d610b2b610b04610aeb60208501612182565b73ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390a18061212e565b906000915b808310610b5157505050610b4c906120a6565b610a62565b90919497610b8c610b86610b9292610b808c8b610b7982610b738e8b8d611b38565b92611b16565b5191611fdf565b90611efd565b996120a6565b956120a6565b9190610b39565b610ba48186886120e0565b610bae818061212e565b9091610bbc60208201612182565b73ffffffffffffffffffffffffffffffffffffffff169260005b87848210610ce157505083610bf8575b50505050610bf3906120a6565b610a53565b610c1160409a97949a9996939998959289810190611cf0565b8b3b15610308578b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610c54946122c1565b03815a93600094fa9081610cc8575b50610cb35786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b94975092955090935091610bf3388080610be6565b80610cd5610cdb926103b1565b80610f26565b38610c63565b87610d17610d09610d0f8986610cfe610d22989e610d1c98611b16565b519384918c8b611b38565b86612bed565b50918c6127a0565b6120a6565b966120a6565b610bd6565b610d4a610d5091610d42610d3c85888a6120e0565b8061212e565b919050611efd565b916120a6565b90610a3e565b50346103085760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610308576105bf73ffffffffffffffffffffffffffffffffffffffff600435610daa81610435565b608060409283928351610dbc8161036b565b600093818580935282602082015282878201528260608201520152168152806020522090610e4f67ffffffffffffffff6001835194610dfa8661036b565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019067ffffffffffffffff169052565b5191829182919091608067ffffffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103085760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085773ffffffffffffffffffffffffffffffffffffffff600435610efd81610435565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261030857565b50346103085760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261030857602060405160018152f35b50346103085760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085760043567ffffffffffffffff811161030857610fbe602491369060040161030d565b90610ff46040519283927f570e1a360000000000000000000000000000000000000000000000000000000084526004840161278f565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af19182156110a6575b600092611076575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61109891925060203d811161109f575b61109081836103c5565b81019061277a565b9038611046565b503d611086565b6110ae611eab565b61103e565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc90602082820112610308576004359167ffffffffffffffff83116103085782610160920301126103085760040190565b503461030857602061111d611118366110b3565b61256f565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085761002160043561115f81610435565b615568565b5034610308576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126112e5573381528060205260408120600181019063ffffffff825416908115611287576112226111e561124a936111d56111d0855460ff9060701c1690565b6158d0565b67ffffffffffffffff4216615935565b84547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff16602082901b6bffffffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405167ffffffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b5034610308576112f7366110b3565b6112ff6119f6565b6113098183612a66565b509081600182146115ce575b6001146115c5575b801515806115bc575b6114dd57811515806114d4575b61138a5760806113498460849643600052611f0a565b93015192604051937fa30fd31e0000000000000000000000000000000000000000000000000000000085526004850152602484015260448301526064820152fd5b50815160a0015173ffffffffffffffffffffffffffffffffffffffff16907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611451576040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601460648201527f41413334207369676e6174757265206572726f72000000000000000000000000608482015260a490fd5b6040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601660648201527f41413332207061796d6173746572206578706972656400000000000000000000608482015260a490fd5b50428210611333565b600103611550576040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601460648201527f41413234207369676e6174757265206572726f72000000000000000000000000608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152600c60648201527f4141323220657870697265640000000000000000000000000000000000000000608482015260a490fd5b50428110611326565b6000915061131d565b60009150611315565b50346103085760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085760043561161381610435565b6109ca73ffffffffffffffffffffffffffffffffffffffff6116553373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9261171161167861092486546dffffffffffffffffffffffffffff9060781c1690565b94611684861515615951565b6116e9600182016116c167ffffffffffffffff6116ad835467ffffffffffffffff9060201c1690565b166116b98115156159b6565b421015615a1b565b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af161176e611bcf565b50615a80565b503461030857611783366110b3565b61178b6119f6565b6117958183612a66565b6117c36117be60a086949596510173ffffffffffffffffffffffffffffffffffffffff90511690565b6153ea565b916118206117f86117ed6117be845173ffffffffffffffffffffffffffffffffffffffff90511690565b976040810190611cf0565b9060006014831061190f57506118146117be9261181a92612601565b9061260f565b60601c90565b93608082015195606060408401519301519261183a610406565b978852602088015260408701526060860152608085015273ffffffffffffffffffffffffffffffffffffffff81166118a3575061086b916040519485947f3dd956e900000000000000000000000000000000000000000000000000000000865260048601612720565b9061086b926118b1836153ea565b6118d86118bc610415565b73ffffffffffffffffffffffffffffffffffffffff9095168552565b60208401526040519586957fca2d82d80000000000000000000000000000000000000000000000000000000087526004870161268e565b9150506153ea565b50346103085760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085773ffffffffffffffffffffffffffffffffffffffff60043561196881610435565b16600052600060205260a0604060002067ffffffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff81116119e9575b60051b0190565b6119f161033b565b6119e2565b60405190611a038261036b565b604051608083610100830167ffffffffffffffff811184821017611a6c575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611a7461033b565b611a22565b90611a83826119cf565b611a9060405191826103c5565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611abe82946119cf565b019060005b828110611acf57505050565b602090611ada6119f6565b82828501015201611ac3565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611b2b575b60051b010190565b611b33611ae6565b611b23565b9190811015611b79575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610308570190565b611b81611ae6565b611b42565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111611bc2575b01160190565b611bca61033b565b611bbc565b3d15611bfa573d90611be082611b86565b91611bee60405193846103c5565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611c9257600080809381935af1611c2c611bcf565b5015611c3457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610308570180359067ffffffffffffffff82116103085760200191813603831361030857565b90816020910312610308575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b838110611da25750506000910152565b8181015183820152602001611d92565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093611dee81518092818752878088019101611d8f565b0116010190565b90611e0f60809161063896946101c0808652850191611d50565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a0818403910152611db2565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b91908203918211611ef557565b610413611eb8565b91908201809211611ef557565b5a90826020611f226060830151936060810190611cf0565b90611f5b8560405198899485947f1d73275600000000000000000000000000000000000000000000000000000000865260048601611df5565b03816000305af160009481611faf575b50611fa95761063893505a8303928311611f9c575b6080810151830180931115614aee57611f97611eb8565b614aee565b611fa4611eb8565b611f80565b50505090565b611fd191955060203d8111611fd8575b611fc981836103c5565b810190611d41565b9338611f6b565b503d611fbf565b90825a926020611ff86060840151946060810190611cf0565b9061203186604051998a9485947f1d73275600000000000000000000000000000000000000000000000000000000865260048601611df5565b03816000305af160009581612086575b5061207f5761063894505a8403938411612072575b6080820151840180941115614e1f5761206d611eb8565b614e1f565b61207a611eb8565b612056565b5050505090565b61209f91965060203d8111611fd857611fc981836103c5565b9438612041565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146120d4570190565b6120dc611eb8565b0190565b9190811015612121575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610308570190565b612129611ae6565b6120ea565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610308570180359067ffffffffffffffff821161030857602001918160051b3603831361030857565b3561063881610435565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561030857016020813591019167ffffffffffffffff821161030857813603831361030857565b61063891612207816121ed8461046d565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526122a2612253612238612227604086018661218c565b610160806040880152860191611d50565b612245606086018661218c565b908583036060870152611d50565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206122958186018661218c565b9185840390860152611d50565b916122b3610140918281019061218c565b929091818503910152611d50565b949391929083604087016040885252606086019360608160051b8801019482600090815b8483106123045750505050505084602061063895968503910152611d50565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea18436030181121561237f576001918461236d92016121dc565b986020908101969501930191906122e5565b8280fd5b1561238a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b908092918237016000815290565b604090610638939281528160208201520190611db2565b92919261241982611b86565b9161242760405193846103c5565b829481845281830111610308578281602093846000960137010152565b91909261063894935a90612459303314612383565b835190600095818792612487575b5050505090612481915a900360808401510194369161240d565b916150e0565b908291826124a9865173ffffffffffffffffffffffffffffffffffffffff1690565b6040870151936124be604051809581936123e8565b0393f1906124ca611bcf565b91156124d9575b808691612467565b6124819392955081516124f4575b50506001939091386124d1565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926125656020612553835173ffffffffffffffffffffffffffffffffffffffff1690565b920151956040519384931696836123f6565b0390a338806124e7565b8061257e610140820182611cf0565b50037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081016040519182016040528082526020820192833751902060405160208101918252306040820152466060820152606081526080810181811067ffffffffffffffff8211176125f4575b60405251902090565b6125fc61033b565b6125eb565b906014116103085790601490565b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000903581811693926014811061264457505050565b60140360031b82901b16169150565b9060a0608061063893805184526020810151602085015260408101516040850152606081015160608501520151918160808201520190611db2565b92946126ef610413956126dd6101009599986126cb6126b7602097610140808c528b0190612653565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b6127696104139461275761274260a0959998969960e0865260e0860190612653565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b90816020910312610308575161063881610435565b916020610638938181520191611d50565b91801515806129f8575b61291457508215158061290b575b6127c157505050565b5160a0015173ffffffffffffffffffffffffffffffffffffffff16917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612887576040517efa072b000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601460648201527f41413334207369676e6174757265206572726f72000000000000000000000000608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601660648201527f41413332207061796d6173746572206578706972656400000000000000000000608482015260a490fd5b504283106127b8565b60011415905061298b576040517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152601460648201527f41413234207369676e6174757265206572726f72000000000000000000000000608482015260a490fd5b6040517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152600c60648201527f4141323220657870697265640000000000000000000000000000000000000000608482015260a490fd5b504281106127aa565b15612a0857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b91906000915a91805194612a7a8682612ddc565b612a838161256f565b6020830152612ac16effffffffffffffffffffffffffffff60808801516060890151176040890151176101008401359060e085013517171115612a01565b612aca86612e9e565b93612ad68584846133f2565b9891969096612ae443600052565b60a0606093019073ffffffffffffffffffffffffffffffffffffffff612b1e835173ffffffffffffffffffffffffffffffffffffffff1690565b16612bd3575b505a840360a086013510612b505750604085015260608401526080919060c0905a900391013501910152565b516040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260606044820152601e60648201527f41413430206f76657220766572696669636174696f6e4761734c696d69740000608482015260a490fd5b90925081612be492995086866144ef565b97909138612b24565b91939092936000935a8251612c028184612ddc565b612c0b8361256f565b6020850152612c496effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e087013517171115612a01565b612c5f612c5582612e9e565b809986868a6138dc565b9991979097612c6d43600052565b60a0606094019073ffffffffffffffffffffffffffffffffffffffff612ca7835173ffffffffffffffffffffffffffffffffffffffff1690565b16612d5c575b505a850360a087013510612cda575050604085015260608401526080919060c0905a900391013501910152565b516040517efa072b000000000000000000000000000000000000000000000000000000008152600481019290925273ffffffffffffffffffffffffffffffffffffffff16602482015260606044820152601e60648201527f41413430206f76657220766572696669636174696f6e4761734c696d69740000608482015260a490fd5b909350819950828787612d6e946147d9565b98909238612cad565b15612d7e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b612e4e90612e06612dec82612182565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611cf0565b908115612e9357612e7861181a6118148460a094612e73601461041399981015612d77565b612601565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff1615612ee457612ee060035b60ff6040840151911660608401510201608083015101916153c2565b0290565b612ee06001612ec4565b612f06606092959493956080835260808301906121dc565b946020820152600060408201520152565b90606092959493612f4573ffffffffffffffffffffffffffffffffffffffff926080855260808501906121dc565b9660208401521660408201520152565b60009060033d11612f6257565b905060046000803e60005160e01c90565b600060443d10610638576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612fef57818401948551938411612ff7573d85010160208487010111612fef5750610638929101602001906103c5565b949350505050565b50949350505050565b9060606106389260008152600060208201528160408201520190611db2565b60609061063893928152600060208201528160408201520190611db2565b60609073ffffffffffffffffffffffffffffffffffffffff6106389493600083521660208201528160408201520190611db2565b73ffffffffffffffffffffffffffffffffffffffff610638949360609383521660208201528160408201520190611db2565b600093849384935a9461316e60208451936130d2855173ffffffffffffffffffffffffffffffffffffffff1690565b956130eb6130e36040840184611cf0565b90838c6140d6565b84918573ffffffffffffffffffffffffffffffffffffffff928361312660a08b015173ffffffffffffffffffffffffffffffffffffffff1690565b1615988961338a575b60600151908601516040517f0825d1fc000000000000000000000000000000000000000000000000000000008152978896879586939060048501612eee565b03938a1690f182918161336a575b50613361575060019061318d612f55565b6308c379a014613316575b506132aa575b6131ac575b5050505a900392565b6131d69073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b916131f261092484546dffffffffffffffffffffffffffff1690565b9081831161323d575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff161790553880806131a3565b6040517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152601760648201527f41413231206469646e2774207061792070726566756e64000000000000000000608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481018590526000602482015260606044820152601660648201527f4141323320726576657274656420286f72204f4f472900000000000000000000608482015260a490fd5b61331e612f73565b908161332a5750613198565b86905061086b6040519283927efa072b0000000000000000000000000000000000000000000000000000000084526004840161301f565b965061319e9050565b61338391925060203d8111611fd857611fc981836103c5565b903861317c565b94506133d06109246133bc8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b8111156133e75750856060835b9691505061312f565b606087918d036133de565b9190916000915a9184519061341b825173ffffffffffffffffffffffffffffffffffffffff1690565b9161343361342c6040840184611cf0565b9089613dbc565b61343c43600052565b823b156138705760a08101805173ffffffffffffffffffffffffffffffffffffffff168015159081613866575b506137fa5773ffffffffffffffffffffffffffffffffffffffff8416926040517f3ad59dbc000000000000000000000000000000000000000000000000000000008152602081600481885afa600091816137d9575b506137d157506000986000915b73ffffffffffffffffffffffffffffffffffffffff6135006000955173ffffffffffffffffffffffffffffffffffffffff1690565b16159586613775575b60009060206060819798015194015192613552604051988997889687947f0825d1fc00000000000000000000000000000000000000000000000000000000865260048601612f17565b0393f160009181613754575b5061374d5750600161356e612f55565b6308c379a014613705575b613699575b61358b575b50505a900392565b6135b59073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b6135d061092482546dffffffffffffffffffffffffffff1690565b80831161362d57613626926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613583565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601760648201527f41413231206469646e2774207061792070726566756e64000000000000000000608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601660648201527f4141323320726576657274656420286f72204f4f472900000000000000000000608482015260a490fd5b61370d612f73565b806137185750613579565b61086b906040519182917efa072b00000000000000000000000000000000000000000000000000000000835260048301613000565b945061357e565b61376e91925060203d602011611fd857611fc981836103c5565b903861355e565b602094506000906137ac6109246133bc8b73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b8a811183146137c65750856060835b975050509050613509565b606087918c036137bb565b9889916134cb565b6137f391925060203d60201161109f5761109081836103c5565b90386134be565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601b60648201527f41413330207061796d6173746572206e6f74206465706c6f7965640000000000608482015260a490fd5b90503b1538613469565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601960648201527f41413230206163636f756e74206e6f74206465706c6f79656400000000000000608482015260a490fd5b9091929360009460009384955a95815161390a815173ffffffffffffffffffffffffffffffffffffffff1690565b9360409561392561391d88840184611cf0565b90878c6140d6565b73ffffffffffffffffffffffffffffffffffffffff600181831614613c2c575b8492858261396a60a088015173ffffffffffffffffffffffffffffffffffffffff1690565b16159788613bd4575b602060608197980151910151926139b88c51988997889687947f0825d1fc00000000000000000000000000000000000000000000000000000000865260048601612f17565b03938a1690f1829181613bb4575b50613bab57506001906139d7612f55565b6308c379a014613b61575b50613af6575b6139f7575b505050505a900392565b613a219073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b92613a3d61092485546dffffffffffffffffffffffffffff1690565b91828411613a8a57505082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080806139ed565b517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152601760648201527f41413231206469646e2774207061792070726566756e64000000000000000000608482015260a49150fd5b82517efa072b000000000000000000000000000000000000000000000000000000008152600481018690526000602482015260606044820152601660648201527f4141323320726576657274656420286f72204f4f472900000000000000000000608482015260a490fd5b613b69612f73565b9081613b7557506139e2565b61086b86899250519283927efa072b0000000000000000000000000000000000000000000000000000000084526004840161301f565b97506139e89050565b613bcd91925060203d8111611fd857611fc981836103c5565b90386139c6565b60209550613c086109246133bc8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b8c80821115613c21575050856060835b97505050613973565b879160609103613c18565b9b5050613c3843600052565b843b15613d515760a082015173ffffffffffffffffffffffffffffffffffffffff168b811615159081613d47575b50613cdc57600460208c8851928380927f3ad59dbc0000000000000000000000000000000000000000000000000000000082528a165afa849181613cbc575b50613cb45750829a8390613945565b9a8b90613945565b613cd591925060203d811161109f5761109081836103c5565b9038613ca5565b85517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601b60648201527f41413330207061796d6173746572206e6f74206465706c6f7965640000000000608482015260a490fd5b90503b1538613c66565b85517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601960648201527f41413230206163636f756e74206e6f74206465706c6f79656400000000000000608482015260a490fd5b909180613dc857505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b61406a57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e2787876004840161278f565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f191821561405d575b60009261403d575b50808216958615613fd15716809503613f65573b15613ef95761181a6118147fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613ec093612601565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152602060648201527f4141313520696e6974436f6465206d757374206372656174652073656e646572608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152602060648201527f4141313420696e6974436f6465206d7573742072657475726e2073656e646572608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601b60648201527f4141313320696e6974436f6465206661696c6564206f72204f4f470000000000608482015260a490fd5b61405691925060203d811161109f5761109081836103c5565b9038613e76565b614065611eab565b613e6e565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601f60648201527f414131302073656e64657220616c726561647920636f6e737472756374656400608482015260a490fd5b929091816140e5575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b61439057606084510151604051907f570e1a360000000000000000000000000000000000000000000000000000000082526020828061414488886004840161278f565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f1918215614383575b600092614363575b508082169687156142f7571680960361428b573b1561421e575061181a6118147fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d936141de93612601565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3388080806140df565b6040517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152602060648201527f4141313520696e6974436f6465206d757374206372656174652073656e646572608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481018390526000602482015260606044820152602060648201527f4141313420696e6974436f6465206d7573742072657475726e2073656e646572608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481018590526000602482015260606044820152601b60648201527f4141313320696e6974436f6465206661696c6564206f72204f4f470000000000608482015260a490fd5b61437c91925060203d811161109f5761109081836103c5565b9038614193565b61438b611eab565b61418b565b6040517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152601f60648201527f414131302073656e64657220616c726561647920636f6e737472756374656400608482015260a490fd5b1561440457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261030857825167ffffffffffffffff81116103085783019080601f830112156103085781519161449983611b86565b916144a760405193846103c5565b83835260208483010111610308576020926144c791848085019101611d8f565b92015190565b6144e5604092959493956060835260608301906121dc565b9460208201520152565b939193606094600094600092845161452d60a08a830151926145128685116143fd565b015173ffffffffffffffffffffffffffffffffffffffff1690565b956145588773ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61457361092482546dffffffffffffffffffffffffffff1690565b868110614758579260208795936145d78a9896946dffffffffffffffffffffffffffff6146109b8b9703166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015192604051978896879586937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016144cd565b039373ffffffffffffffffffffffffffffffffffffffff8a169103f1908183918493614732575b5061472a575050600190614649612f55565b6308c379a0146146df575b5061465c5750565b6040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601660648201527f4141333320726576657274656420286f72204f4f472900000000000000000000608482015260a490fd5b6146e7612f73565b90816146f35750614654565b83905061086b6040519283927efa072b0000000000000000000000000000000000000000000000000000000084526004840161303d565b955093505050565b90925061475191503d8085833e61474981836103c5565b810190614462565b9138614637565b6040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff8a16602482015260606044820152601e60648201527f41413331207061796d6173746572206465706f73697420746f6f206c6f770000608482015260a490fd5b9094929460609560009560009285516147fd60a08b830151926145128685116143fd565b966148288873ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61484361092482546dffffffffffffffffffffffffffff1690565b8681106149ea579260208795936145d78a9896946dffffffffffffffffffffffffffff6148a79b8b9703166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b039373ffffffffffffffffffffffffffffffffffffffff8b169103f19081839184936149cc575b506149c35750506001906148e0612f55565b6308c379a014614978575b506148f4575050565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601660648201527f4141333320726576657274656420286f72204f4f472900000000000000000000608482015260a490fd5b614980612f73565b908161498c57506148eb565b61086b9250506040519384937efa072b00000000000000000000000000000000000000000000000000000000855260048501613071565b96509450505050565b9092506149e391503d8085833e61474981836103c5565b91386148ce565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff8b16602482015260606044820152601e60648201527f41413331207061796d6173746572206465706f73697420746f6f206c6f770000608482015260a490fd5b60031115614a7557565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614ac260409160028652606060208701526060860190611db2565b930152565b939291906003811015614a7557604091614ac2918652606060208701526060860190611db2565b909291925a916000918151614b02816153c2565b9260a0820195614b26875173ffffffffffffffffffffffffffffffffffffffff1690565b9873ffffffffffffffffffffffffffffffffffffffff94858b1680614ca6575050835173ffffffffffffffffffffffffffffffffffffffff16915b5a9003019485029860408301908a825110614c2357507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bae614c1e938c602094510390615477565b015194896020614bf0614bd5865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601f60648201527f4135312070726566756e642062656c6f772061637475616c476173436f737400608482015260a490fd5b8b93918051614cb7575b5050614b61565b606087015160009a509091803b15614e1b57918a918a83614d0a956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614aa4565b0393f19081614e08575b50614e03576001614d23612f55565b6308c379a014614dbb575b614d3a575b3880614cb0565b6040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff8c16602482015260606044820152601160648201527f41353020706f73744f7020726576657274000000000000000000000000000000608482015260a490fd5b614dc3612f73565b80614dce5750614d2e565b8c61086b6040519283927efa072b0000000000000000000000000000000000000000000000000000000084526004840161303d565b614d33565b80610cd5614e15926103b1565b38614d14565b8a80fd5b919392935a90600092805190614e34826153c2565b9360a0830196614e58885173ffffffffffffffffffffffffffffffffffffffff1690565b9973ffffffffffffffffffffffffffffffffffffffff95868c1680614f65575050845173ffffffffffffffffffffffffffffffffffffffff16925b5a9003019586029960408401918b835110614ee15750507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bae614c1e938c602094510390615477565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601f60648201527f4135312070726566756e642062656c6f772061637475616c476173436f737400608482015260a490fd5b8c94918051614f76575b5050614e93565b606088015160009b509091803b156150dc57918b918b83614fc9956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614aa4565b0393f190816150c9575b506150c4576001614fe2612f55565b6308c379a01461507a575b614ff9575b3880614f6f565b6040517efa072b0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff8d16602482015260606044820152601160648201527f41353020706f73744f7020726576657274000000000000000000000000000000608482015260a490fd5b615082612f73565b8061508d5750614fed565b8461086b8f926040519384937efa072b00000000000000000000000000000000000000000000000000000000855260048501613071565b614ff2565b80610cd56150d6926103b1565b38614fd3565b8b80fd5b909392935a9281516150f1816153c2565b9260a0820195615115875173ffffffffffffffffffffffffffffffffffffffff1690565b9873ffffffffffffffffffffffffffffffffffffffff94858b1690816151fa575050835173ffffffffffffffffffffffffffffffffffffffff16915b5a9003019485029860408301908a825110614c2357507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94939261519e614c1e938c602094510390615477565b6151a788614a6b565b0151948960206151ce614bd5865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b8b9391815161520b575b5050615151565b8884026152178b614a6b565b60028b146152a2576060880151823b156103085761526a93600080948e604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614ac7565b0393f18015615295575b615282575b505b3880615204565b80610cd561528f926103b1565b38615279565b61529d611eab565b615274565b6060880151823b15610308576152ed93600080948e604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614ac7565b0393f190816153af575b506153aa576001615306612f55565b6308c379a014615397575b1561527b576040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff8c16602482015260606044820152601160648201527f41353020706f73744f7020726576657274000000000000000000000000000000608482015260a490fd5b61539f612f73565b80614dce5750615311565b61527b565b80610cd56153bc926103b1565b386152f7565b60e060c08201519101518082146153e6574801808210156153e1575090565b905090565b5090565b906040516040810181811067ffffffffffffffff821117615461575b6040526000815263ffffffff600160208301926000845273ffffffffffffffffffffffffffffffffffffffff81961660005260006020526040600020906dffffffffffffffffffffffffffff825460781c1690520154169052565b61546961033b565b615406565b61041333615568565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161555b575b8083116154fd5761041392166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615563611eb8565b6154b8565b73ffffffffffffffffffffffffffffffffffffffff906155883482615477565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b156155db57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561564057565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b156156a557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b1561570a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9067ffffffffffffffff60806001610413946157ca6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff6bffffffffffffffff0000000083549260201b169116179055565b156158d757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909167ffffffffffffffff80809416911601918211611ef557565b1561595857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b156159bd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615a2257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615a8757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615aec57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fdfea2646970667358221220f62d62b69d4218f22a830ae2d98d937e70f79546182a61f6f02799b95670518f64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212202f6aa68977bad9c275e51acad9826417c06681f8af8a6c6afc77efd76d949f2964736f6c63430008110033
Deployed Bytecode
0x60806040526004361015610023575b361561001957600080fd5b61002161546e565b005b60003560e01c80630396cb60146101635780631d7327561461015a5780631fad948c14610151578063205c2878146101485780634b1d7cf51461013f5780635287ce121461013657806370a082311461012d5780638f41ec5a146101245780639b249f691461011b578063a619353114610112578063b760faf914610109578063bb9fe6bf14610100578063c2077116146100f7578063c23a5cea146100ee578063ee219423146100e55763fc7e286d0361000e576100e0611917565b61000e565b506100e0611774565b506100e06115d7565b506100e06112e8565b506100e0611164565b506100e0611125565b506100e0611104565b506100e0610f6c565b506100e0610f31565b506100e0610eac565b506100e0610d56565b506100e0610a2b565b506100e061088c565b506100e061063b565b506100e0610478565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085760043563ffffffff8116808203610308576103037fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102216101f13373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b916101fd8115156155d4565b61021a610211600185015463ffffffff1690565b63ffffffff1690565b1115615639565b54926102e56dffffffffffffffffffffffffffff946102a361024834888460781c16611efd565b9661025488151561569e565b61025f818910615703565b6102838161026b610406565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526102e03373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b615768565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b9181601f840112156103085782359167ffffffffffffffff8311610308576020838186019501011161030857565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761038757604052565b61038f61033b565b604052565b610100810190811067ffffffffffffffff82111761038757604052565b67ffffffffffffffff811161038757604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761038757604052565b604051906104138261036b565b565b604051906040820182811067ffffffffffffffff82111761038757604052565b73ffffffffffffffffffffffffffffffffffffffff81160361030857565b6024359061041382610435565b60c4359061041382610435565b359061041382610435565b5034610308576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085767ffffffffffffffff600435818111610308576104ca90369060040161030d565b367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc019291610180841261030857610100604051946105088661036b565b126103085760405161051981610394565b610521610453565b815260443560208201526064356040820152608435606082015260a435608082015261054b610460565b60a082015260e43560c08201526101043560e082015284526101243560208501526101443560408501526101643560608501526101843560808501526101a435928311610308576105bf936105a76105af94369060040161030d565b939092612444565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103085760043567ffffffffffffffff9283821161030857806023830112156103085781600401359384116103085760248460051b8301011161030857602401919060243561063881610435565b90565b50346103085761064a366105c3565b610655829392611a79565b60005b8481106106a7575060009283915b858310610677576100218585611bff565b90919360019061069d61068b878987611b38565b6106958886611b16565b519088611fdf565b0194019190610666565b6106b381839593611b16565b516106bf828785611b38565b6000915a8151926106d08482612ddc565b6106d98161256f565b6020840152608091828501519460609586820151179561071f6effffffffffffffffffffffffffffff60409889850151176101008701359060e088013517171115612a01565b61072882612e9e565b6107348188878d6130a3565b9991905061074143600052565b839460a0809101918d73ffffffffffffffffffffffffffffffffffffffff61077d855173ffffffffffffffffffffffffffffffffffffffff1690565b1661086f575b50505a870390880135106107c457509260c0926107bb9997959289979560019d9c9a01528601525a90039101350190820152846127a0565b01929092610658565b61086b6107e68d925173ffffffffffffffffffffffffffffffffffffffff1690565b92519283927efa072b000000000000000000000000000000000000000000000000000000008452600484019060a09273ffffffffffffffffffffffffffffffffffffffff91835216602082015260606040820152601e60608201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060808201520190565b0390fd5b610882939d508591929750898c916147d9565b9a9094388d610783565b50346103085760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610308576004356108c881610435565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff815416928383116109cd57848373ffffffffffffffffffffffffffffffffffffffff829593610970849661093761092487986109ca9c611ee8565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af16109c4611bcf565b50615ae5565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b503461030857610a3a366105c3565b6000805b838210610d2757610a4f9150611a79565b6000805b848110610b9957505060008093815b818110610aaa5761002186867f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d60405180610aa281906000602083019252565b0390a1611bff565b610b34610ab882848a6120e0565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d610b2b610b04610aeb60208501612182565b73ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390a18061212e565b906000915b808310610b5157505050610b4c906120a6565b610a62565b90919497610b8c610b86610b9292610b808c8b610b7982610b738e8b8d611b38565b92611b16565b5191611fdf565b90611efd565b996120a6565b956120a6565b9190610b39565b610ba48186886120e0565b610bae818061212e565b9091610bbc60208201612182565b73ffffffffffffffffffffffffffffffffffffffff169260005b87848210610ce157505083610bf8575b50505050610bf3906120a6565b610a53565b610c1160409a97949a9996939998959289810190611cf0565b8b3b15610308578b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610c54946122c1565b03815a93600094fa9081610cc8575b50610cb35786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b94975092955090935091610bf3388080610be6565b80610cd5610cdb926103b1565b80610f26565b38610c63565b87610d17610d09610d0f8986610cfe610d22989e610d1c98611b16565b519384918c8b611b38565b86612bed565b50918c6127a0565b6120a6565b966120a6565b610bd6565b610d4a610d5091610d42610d3c85888a6120e0565b8061212e565b919050611efd565b916120a6565b90610a3e565b50346103085760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610308576105bf73ffffffffffffffffffffffffffffffffffffffff600435610daa81610435565b608060409283928351610dbc8161036b565b600093818580935282602082015282878201528260608201520152168152806020522090610e4f67ffffffffffffffff6001835194610dfa8661036b565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019067ffffffffffffffff169052565b5191829182919091608067ffffffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103085760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085773ffffffffffffffffffffffffffffffffffffffff600435610efd81610435565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261030857565b50346103085760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261030857602060405160018152f35b50346103085760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085760043567ffffffffffffffff811161030857610fbe602491369060040161030d565b90610ff46040519283927f570e1a360000000000000000000000000000000000000000000000000000000084526004840161278f565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000001c3ca7717162d72dd5b34c2e16af988fa4980497165af19182156110a6575b600092611076575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61109891925060203d811161109f575b61109081836103c5565b81019061277a565b9038611046565b503d611086565b6110ae611eab565b61103e565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc90602082820112610308576004359167ffffffffffffffff83116103085782610160920301126103085760040190565b503461030857602061111d611118366110b3565b61256f565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085761002160043561115f81610435565b615568565b5034610308576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126112e5573381528060205260408120600181019063ffffffff825416908115611287576112226111e561124a936111d56111d0855460ff9060701c1690565b6158d0565b67ffffffffffffffff4216615935565b84547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff16602082901b6bffffffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405167ffffffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b5034610308576112f7366110b3565b6112ff6119f6565b6113098183612a66565b509081600182146115ce575b6001146115c5575b801515806115bc575b6114dd57811515806114d4575b61138a5760806113498460849643600052611f0a565b93015192604051937fa30fd31e0000000000000000000000000000000000000000000000000000000085526004850152602484015260448301526064820152fd5b50815160a0015173ffffffffffffffffffffffffffffffffffffffff16907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611451576040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601460648201527f41413334207369676e6174757265206572726f72000000000000000000000000608482015260a490fd5b6040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601660648201527f41413332207061796d6173746572206578706972656400000000000000000000608482015260a490fd5b50428210611333565b600103611550576040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601460648201527f41413234207369676e6174757265206572726f72000000000000000000000000608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152600c60648201527f4141323220657870697265640000000000000000000000000000000000000000608482015260a490fd5b50428110611326565b6000915061131d565b60009150611315565b50346103085760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085760043561161381610435565b6109ca73ffffffffffffffffffffffffffffffffffffffff6116553373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9261171161167861092486546dffffffffffffffffffffffffffff9060781c1690565b94611684861515615951565b6116e9600182016116c167ffffffffffffffff6116ad835467ffffffffffffffff9060201c1690565b166116b98115156159b6565b421015615a1b565b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af161176e611bcf565b50615a80565b503461030857611783366110b3565b61178b6119f6565b6117958183612a66565b6117c36117be60a086949596510173ffffffffffffffffffffffffffffffffffffffff90511690565b6153ea565b916118206117f86117ed6117be845173ffffffffffffffffffffffffffffffffffffffff90511690565b976040810190611cf0565b9060006014831061190f57506118146117be9261181a92612601565b9061260f565b60601c90565b93608082015195606060408401519301519261183a610406565b978852602088015260408701526060860152608085015273ffffffffffffffffffffffffffffffffffffffff81166118a3575061086b916040519485947f3dd956e900000000000000000000000000000000000000000000000000000000865260048601612720565b9061086b926118b1836153ea565b6118d86118bc610415565b73ffffffffffffffffffffffffffffffffffffffff9095168552565b60208401526040519586957fca2d82d80000000000000000000000000000000000000000000000000000000087526004870161268e565b9150506153ea565b50346103085760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103085773ffffffffffffffffffffffffffffffffffffffff60043561196881610435565b16600052600060205260a0604060002067ffffffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff81116119e9575b60051b0190565b6119f161033b565b6119e2565b60405190611a038261036b565b604051608083610100830167ffffffffffffffff811184821017611a6c575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611a7461033b565b611a22565b90611a83826119cf565b611a9060405191826103c5565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611abe82946119cf565b019060005b828110611acf57505050565b602090611ada6119f6565b82828501015201611ac3565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611b2b575b60051b010190565b611b33611ae6565b611b23565b9190811015611b79575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610308570190565b611b81611ae6565b611b42565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111611bc2575b01160190565b611bca61033b565b611bbc565b3d15611bfa573d90611be082611b86565b91611bee60405193846103c5565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611c9257600080809381935af1611c2c611bcf565b5015611c3457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610308570180359067ffffffffffffffff82116103085760200191813603831361030857565b90816020910312610308575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b838110611da25750506000910152565b8181015183820152602001611d92565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093611dee81518092818752878088019101611d8f565b0116010190565b90611e0f60809161063896946101c0808652850191611d50565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a0818403910152611db2565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b91908203918211611ef557565b610413611eb8565b91908201809211611ef557565b5a90826020611f226060830151936060810190611cf0565b90611f5b8560405198899485947f1d73275600000000000000000000000000000000000000000000000000000000865260048601611df5565b03816000305af160009481611faf575b50611fa95761063893505a8303928311611f9c575b6080810151830180931115614aee57611f97611eb8565b614aee565b611fa4611eb8565b611f80565b50505090565b611fd191955060203d8111611fd8575b611fc981836103c5565b810190611d41565b9338611f6b565b503d611fbf565b90825a926020611ff86060840151946060810190611cf0565b9061203186604051998a9485947f1d73275600000000000000000000000000000000000000000000000000000000865260048601611df5565b03816000305af160009581612086575b5061207f5761063894505a8403938411612072575b6080820151840180941115614e1f5761206d611eb8565b614e1f565b61207a611eb8565b612056565b5050505090565b61209f91965060203d8111611fd857611fc981836103c5565b9438612041565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146120d4570190565b6120dc611eb8565b0190565b9190811015612121575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610308570190565b612129611ae6565b6120ea565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610308570180359067ffffffffffffffff821161030857602001918160051b3603831361030857565b3561063881610435565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561030857016020813591019167ffffffffffffffff821161030857813603831361030857565b61063891612207816121ed8461046d565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526122a2612253612238612227604086018661218c565b610160806040880152860191611d50565b612245606086018661218c565b908583036060870152611d50565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206122958186018661218c565b9185840390860152611d50565b916122b3610140918281019061218c565b929091818503910152611d50565b949391929083604087016040885252606086019360608160051b8801019482600090815b8483106123045750505050505084602061063895968503910152611d50565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea18436030181121561237f576001918461236d92016121dc565b986020908101969501930191906122e5565b8280fd5b1561238a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b908092918237016000815290565b604090610638939281528160208201520190611db2565b92919261241982611b86565b9161242760405193846103c5565b829481845281830111610308578281602093846000960137010152565b91909261063894935a90612459303314612383565b835190600095818792612487575b5050505090612481915a900360808401510194369161240d565b916150e0565b908291826124a9865173ffffffffffffffffffffffffffffffffffffffff1690565b6040870151936124be604051809581936123e8565b0393f1906124ca611bcf565b91156124d9575b808691612467565b6124819392955081516124f4575b50506001939091386124d1565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926125656020612553835173ffffffffffffffffffffffffffffffffffffffff1690565b920151956040519384931696836123f6565b0390a338806124e7565b8061257e610140820182611cf0565b50037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081016040519182016040528082526020820192833751902060405160208101918252306040820152466060820152606081526080810181811067ffffffffffffffff8211176125f4575b60405251902090565b6125fc61033b565b6125eb565b906014116103085790601490565b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000903581811693926014811061264457505050565b60140360031b82901b16169150565b9060a0608061063893805184526020810151602085015260408101516040850152606081015160608501520151918160808201520190611db2565b92946126ef610413956126dd6101009599986126cb6126b7602097610140808c528b0190612653565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b6127696104139461275761274260a0959998969960e0865260e0860190612653565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b90816020910312610308575161063881610435565b916020610638938181520191611d50565b91801515806129f8575b61291457508215158061290b575b6127c157505050565b5160a0015173ffffffffffffffffffffffffffffffffffffffff16917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612887576040517efa072b000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601460648201527f41413334207369676e6174757265206572726f72000000000000000000000000608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601660648201527f41413332207061796d6173746572206578706972656400000000000000000000608482015260a490fd5b504283106127b8565b60011415905061298b576040517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152601460648201527f41413234207369676e6174757265206572726f72000000000000000000000000608482015260a490fd5b6040517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152600c60648201527f4141323220657870697265640000000000000000000000000000000000000000608482015260a490fd5b504281106127aa565b15612a0857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b91906000915a91805194612a7a8682612ddc565b612a838161256f565b6020830152612ac16effffffffffffffffffffffffffffff60808801516060890151176040890151176101008401359060e085013517171115612a01565b612aca86612e9e565b93612ad68584846133f2565b9891969096612ae443600052565b60a0606093019073ffffffffffffffffffffffffffffffffffffffff612b1e835173ffffffffffffffffffffffffffffffffffffffff1690565b16612bd3575b505a840360a086013510612b505750604085015260608401526080919060c0905a900391013501910152565b516040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260606044820152601e60648201527f41413430206f76657220766572696669636174696f6e4761734c696d69740000608482015260a490fd5b90925081612be492995086866144ef565b97909138612b24565b91939092936000935a8251612c028184612ddc565b612c0b8361256f565b6020850152612c496effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e087013517171115612a01565b612c5f612c5582612e9e565b809986868a6138dc565b9991979097612c6d43600052565b60a0606094019073ffffffffffffffffffffffffffffffffffffffff612ca7835173ffffffffffffffffffffffffffffffffffffffff1690565b16612d5c575b505a850360a087013510612cda575050604085015260608401526080919060c0905a900391013501910152565b516040517efa072b000000000000000000000000000000000000000000000000000000008152600481019290925273ffffffffffffffffffffffffffffffffffffffff16602482015260606044820152601e60648201527f41413430206f76657220766572696669636174696f6e4761734c696d69740000608482015260a490fd5b909350819950828787612d6e946147d9565b98909238612cad565b15612d7e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b612e4e90612e06612dec82612182565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611cf0565b908115612e9357612e7861181a6118148460a094612e73601461041399981015612d77565b612601565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff1615612ee457612ee060035b60ff6040840151911660608401510201608083015101916153c2565b0290565b612ee06001612ec4565b612f06606092959493956080835260808301906121dc565b946020820152600060408201520152565b90606092959493612f4573ffffffffffffffffffffffffffffffffffffffff926080855260808501906121dc565b9660208401521660408201520152565b60009060033d11612f6257565b905060046000803e60005160e01c90565b600060443d10610638576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612fef57818401948551938411612ff7573d85010160208487010111612fef5750610638929101602001906103c5565b949350505050565b50949350505050565b9060606106389260008152600060208201528160408201520190611db2565b60609061063893928152600060208201528160408201520190611db2565b60609073ffffffffffffffffffffffffffffffffffffffff6106389493600083521660208201528160408201520190611db2565b73ffffffffffffffffffffffffffffffffffffffff610638949360609383521660208201528160408201520190611db2565b600093849384935a9461316e60208451936130d2855173ffffffffffffffffffffffffffffffffffffffff1690565b956130eb6130e36040840184611cf0565b90838c6140d6565b84918573ffffffffffffffffffffffffffffffffffffffff928361312660a08b015173ffffffffffffffffffffffffffffffffffffffff1690565b1615988961338a575b60600151908601516040517f0825d1fc000000000000000000000000000000000000000000000000000000008152978896879586939060048501612eee565b03938a1690f182918161336a575b50613361575060019061318d612f55565b6308c379a014613316575b506132aa575b6131ac575b5050505a900392565b6131d69073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b916131f261092484546dffffffffffffffffffffffffffff1690565b9081831161323d575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff161790553880806131a3565b6040517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152601760648201527f41413231206469646e2774207061792070726566756e64000000000000000000608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481018590526000602482015260606044820152601660648201527f4141323320726576657274656420286f72204f4f472900000000000000000000608482015260a490fd5b61331e612f73565b908161332a5750613198565b86905061086b6040519283927efa072b0000000000000000000000000000000000000000000000000000000084526004840161301f565b965061319e9050565b61338391925060203d8111611fd857611fc981836103c5565b903861317c565b94506133d06109246133bc8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b8111156133e75750856060835b9691505061312f565b606087918d036133de565b9190916000915a9184519061341b825173ffffffffffffffffffffffffffffffffffffffff1690565b9161343361342c6040840184611cf0565b9089613dbc565b61343c43600052565b823b156138705760a08101805173ffffffffffffffffffffffffffffffffffffffff168015159081613866575b506137fa5773ffffffffffffffffffffffffffffffffffffffff8416926040517f3ad59dbc000000000000000000000000000000000000000000000000000000008152602081600481885afa600091816137d9575b506137d157506000986000915b73ffffffffffffffffffffffffffffffffffffffff6135006000955173ffffffffffffffffffffffffffffffffffffffff1690565b16159586613775575b60009060206060819798015194015192613552604051988997889687947f0825d1fc00000000000000000000000000000000000000000000000000000000865260048601612f17565b0393f160009181613754575b5061374d5750600161356e612f55565b6308c379a014613705575b613699575b61358b575b50505a900392565b6135b59073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b6135d061092482546dffffffffffffffffffffffffffff1690565b80831161362d57613626926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613583565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601760648201527f41413231206469646e2774207061792070726566756e64000000000000000000608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601660648201527f4141323320726576657274656420286f72204f4f472900000000000000000000608482015260a490fd5b61370d612f73565b806137185750613579565b61086b906040519182917efa072b00000000000000000000000000000000000000000000000000000000835260048301613000565b945061357e565b61376e91925060203d602011611fd857611fc981836103c5565b903861355e565b602094506000906137ac6109246133bc8b73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b8a811183146137c65750856060835b975050509050613509565b606087918c036137bb565b9889916134cb565b6137f391925060203d60201161109f5761109081836103c5565b90386134be565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601b60648201527f41413330207061796d6173746572206e6f74206465706c6f7965640000000000608482015260a490fd5b90503b1538613469565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601960648201527f41413230206163636f756e74206e6f74206465706c6f79656400000000000000608482015260a490fd5b9091929360009460009384955a95815161390a815173ffffffffffffffffffffffffffffffffffffffff1690565b9360409561392561391d88840184611cf0565b90878c6140d6565b73ffffffffffffffffffffffffffffffffffffffff600181831614613c2c575b8492858261396a60a088015173ffffffffffffffffffffffffffffffffffffffff1690565b16159788613bd4575b602060608197980151910151926139b88c51988997889687947f0825d1fc00000000000000000000000000000000000000000000000000000000865260048601612f17565b03938a1690f1829181613bb4575b50613bab57506001906139d7612f55565b6308c379a014613b61575b50613af6575b6139f7575b505050505a900392565b613a219073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b92613a3d61092485546dffffffffffffffffffffffffffff1690565b91828411613a8a57505082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080806139ed565b517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152601760648201527f41413231206469646e2774207061792070726566756e64000000000000000000608482015260a49150fd5b82517efa072b000000000000000000000000000000000000000000000000000000008152600481018690526000602482015260606044820152601660648201527f4141323320726576657274656420286f72204f4f472900000000000000000000608482015260a490fd5b613b69612f73565b9081613b7557506139e2565b61086b86899250519283927efa072b0000000000000000000000000000000000000000000000000000000084526004840161301f565b97506139e89050565b613bcd91925060203d8111611fd857611fc981836103c5565b90386139c6565b60209550613c086109246133bc8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b8c80821115613c21575050856060835b97505050613973565b879160609103613c18565b9b5050613c3843600052565b843b15613d515760a082015173ffffffffffffffffffffffffffffffffffffffff168b811615159081613d47575b50613cdc57600460208c8851928380927f3ad59dbc0000000000000000000000000000000000000000000000000000000082528a165afa849181613cbc575b50613cb45750829a8390613945565b9a8b90613945565b613cd591925060203d811161109f5761109081836103c5565b9038613ca5565b85517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601b60648201527f41413330207061796d6173746572206e6f74206465706c6f7965640000000000608482015260a490fd5b90503b1538613c66565b85517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601960648201527f41413230206163636f756e74206e6f74206465706c6f79656400000000000000608482015260a490fd5b909180613dc857505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b61406a57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e2787876004840161278f565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f0000000000000000000000001c3ca7717162d72dd5b34c2e16af988fa49804971690f191821561405d575b60009261403d575b50808216958615613fd15716809503613f65573b15613ef95761181a6118147fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613ec093612601565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152602060648201527f4141313520696e6974436f6465206d757374206372656174652073656e646572608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152602060648201527f4141313420696e6974436f6465206d7573742072657475726e2073656e646572608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601b60648201527f4141313320696e6974436f6465206661696c6564206f72204f4f470000000000608482015260a490fd5b61405691925060203d811161109f5761109081836103c5565b9038613e76565b614065611eab565b613e6e565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600060048201819052602482015260606044820152601f60648201527f414131302073656e64657220616c726561647920636f6e737472756374656400608482015260a490fd5b929091816140e5575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b61439057606084510151604051907f570e1a360000000000000000000000000000000000000000000000000000000082526020828061414488886004840161278f565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f0000000000000000000000001c3ca7717162d72dd5b34c2e16af988fa49804971690f1918215614383575b600092614363575b508082169687156142f7571680960361428b573b1561421e575061181a6118147fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d936141de93612601565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3388080806140df565b6040517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152602060648201527f4141313520696e6974436f6465206d757374206372656174652073656e646572608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481018390526000602482015260606044820152602060648201527f4141313420696e6974436f6465206d7573742072657475726e2073656e646572608482015260a490fd5b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481018590526000602482015260606044820152601b60648201527f4141313320696e6974436f6465206661696c6564206f72204f4f470000000000608482015260a490fd5b61437c91925060203d811161109f5761109081836103c5565b9038614193565b61438b611eab565b61418b565b6040517efa072b00000000000000000000000000000000000000000000000000000000815260048101919091526000602482015260606044820152601f60648201527f414131302073656e64657220616c726561647920636f6e737472756374656400608482015260a490fd5b1561440457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261030857825167ffffffffffffffff81116103085783019080601f830112156103085781519161449983611b86565b916144a760405193846103c5565b83835260208483010111610308576020926144c791848085019101611d8f565b92015190565b6144e5604092959493956060835260608301906121dc565b9460208201520152565b939193606094600094600092845161452d60a08a830151926145128685116143fd565b015173ffffffffffffffffffffffffffffffffffffffff1690565b956145588773ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61457361092482546dffffffffffffffffffffffffffff1690565b868110614758579260208795936145d78a9896946dffffffffffffffffffffffffffff6146109b8b9703166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015192604051978896879586937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016144cd565b039373ffffffffffffffffffffffffffffffffffffffff8a169103f1908183918493614732575b5061472a575050600190614649612f55565b6308c379a0146146df575b5061465c5750565b6040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601660648201527f4141333320726576657274656420286f72204f4f472900000000000000000000608482015260a490fd5b6146e7612f73565b90816146f35750614654565b83905061086b6040519283927efa072b0000000000000000000000000000000000000000000000000000000084526004840161303d565b955093505050565b90925061475191503d8085833e61474981836103c5565b810190614462565b9138614637565b6040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff8a16602482015260606044820152601e60648201527f41413331207061796d6173746572206465706f73697420746f6f206c6f770000608482015260a490fd5b9094929460609560009560009285516147fd60a08b830151926145128685116143fd565b966148288873ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61484361092482546dffffffffffffffffffffffffffff1690565b8681106149ea579260208795936145d78a9896946dffffffffffffffffffffffffffff6148a79b8b9703166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b039373ffffffffffffffffffffffffffffffffffffffff8b169103f19081839184936149cc575b506149c35750506001906148e0612f55565b6308c379a014614978575b506148f4575050565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601660648201527f4141333320726576657274656420286f72204f4f472900000000000000000000608482015260a490fd5b614980612f73565b908161498c57506148eb565b61086b9250506040519384937efa072b00000000000000000000000000000000000000000000000000000000855260048501613071565b96509450505050565b9092506149e391503d8085833e61474981836103c5565b91386148ce565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff8b16602482015260606044820152601e60648201527f41413331207061796d6173746572206465706f73697420746f6f206c6f770000608482015260a490fd5b60031115614a7557565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614ac260409160028652606060208701526060860190611db2565b930152565b939291906003811015614a7557604091614ac2918652606060208701526060860190611db2565b909291925a916000918151614b02816153c2565b9260a0820195614b26875173ffffffffffffffffffffffffffffffffffffffff1690565b9873ffffffffffffffffffffffffffffffffffffffff94858b1680614ca6575050835173ffffffffffffffffffffffffffffffffffffffff16915b5a9003019485029860408301908a825110614c2357507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bae614c1e938c602094510390615477565b015194896020614bf0614bd5865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601f60648201527f4135312070726566756e642062656c6f772061637475616c476173436f737400608482015260a490fd5b8b93918051614cb7575b5050614b61565b606087015160009a509091803b15614e1b57918a918a83614d0a956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614aa4565b0393f19081614e08575b50614e03576001614d23612f55565b6308c379a014614dbb575b614d3a575b3880614cb0565b6040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff8c16602482015260606044820152601160648201527f41353020706f73744f7020726576657274000000000000000000000000000000608482015260a490fd5b614dc3612f73565b80614dce5750614d2e565b8c61086b6040519283927efa072b0000000000000000000000000000000000000000000000000000000084526004840161303d565b614d33565b80610cd5614e15926103b1565b38614d14565b8a80fd5b919392935a90600092805190614e34826153c2565b9360a0830196614e58885173ffffffffffffffffffffffffffffffffffffffff1690565b9973ffffffffffffffffffffffffffffffffffffffff95868c1680614f65575050845173ffffffffffffffffffffffffffffffffffffffff16925b5a9003019586029960408401918b835110614ee15750507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bae614c1e938c602094510390615477565b6040517efa072b000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff91909116602482015260606044820152601f60648201527f4135312070726566756e642062656c6f772061637475616c476173436f737400608482015260a490fd5b8c94918051614f76575b5050614e93565b606088015160009b509091803b156150dc57918b918b83614fc9956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614aa4565b0393f190816150c9575b506150c4576001614fe2612f55565b6308c379a01461507a575b614ff9575b3880614f6f565b6040517efa072b0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff8d16602482015260606044820152601160648201527f41353020706f73744f7020726576657274000000000000000000000000000000608482015260a490fd5b615082612f73565b8061508d5750614fed565b8461086b8f926040519384937efa072b00000000000000000000000000000000000000000000000000000000855260048501613071565b614ff2565b80610cd56150d6926103b1565b38614fd3565b8b80fd5b909392935a9281516150f1816153c2565b9260a0820195615115875173ffffffffffffffffffffffffffffffffffffffff1690565b9873ffffffffffffffffffffffffffffffffffffffff94858b1690816151fa575050835173ffffffffffffffffffffffffffffffffffffffff16915b5a9003019485029860408301908a825110614c2357507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94939261519e614c1e938c602094510390615477565b6151a788614a6b565b0151948960206151ce614bd5865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b8b9391815161520b575b5050615151565b8884026152178b614a6b565b60028b146152a2576060880151823b156103085761526a93600080948e604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614ac7565b0393f18015615295575b615282575b505b3880615204565b80610cd561528f926103b1565b38615279565b61529d611eab565b615274565b6060880151823b15610308576152ed93600080948e604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614ac7565b0393f190816153af575b506153aa576001615306612f55565b6308c379a014615397575b1561527b576040517efa072b0000000000000000000000000000000000000000000000000000000081526000600482015273ffffffffffffffffffffffffffffffffffffffff8c16602482015260606044820152601160648201527f41353020706f73744f7020726576657274000000000000000000000000000000608482015260a490fd5b61539f612f73565b80614dce5750615311565b61527b565b80610cd56153bc926103b1565b386152f7565b60e060c08201519101518082146153e6574801808210156153e1575090565b905090565b5090565b906040516040810181811067ffffffffffffffff821117615461575b6040526000815263ffffffff600160208301926000845273ffffffffffffffffffffffffffffffffffffffff81961660005260006020526040600020906dffffffffffffffffffffffffffff825460781c1690520154169052565b61546961033b565b615406565b61041333615568565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161555b575b8083116154fd5761041392166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615563611eb8565b6154b8565b73ffffffffffffffffffffffffffffffffffffffff906155883482615477565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b156155db57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561564057565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b156156a557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b1561570a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9067ffffffffffffffff60806001610413946157ca6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff6bffffffffffffffff0000000083549260201b169116179055565b156158d757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909167ffffffffffffffff80809416911601918211611ef557565b1561595857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b156159bd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615a2257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615a8757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615aec57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fdfea2646970667358221220f62d62b69d4218f22a830ae2d98d937e70f79546182a61f6f02799b95670518f64736f6c63430008110033
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.