Overview
ETH Balance
0.225613820796698321 ETH
ETH Value
$759.42 (@ $3,366.01/ETH)More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 15,572 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Handle Ops | 12572242 | 9 days ago | IN | 0 ETH | 0.00010169 | ||||
Handle Ops | 12572242 | 9 days ago | IN | 0 ETH | 0.00010984 | ||||
Handle Ops | 12572210 | 9 days ago | IN | 0 ETH | 0.00007134 | ||||
Handle Ops | 12572210 | 9 days ago | IN | 0 ETH | 0.00007945 | ||||
Handle Ops | 12572162 | 9 days ago | IN | 0 ETH | 0.00006122 | ||||
Handle Ops | 12572162 | 9 days ago | IN | 0 ETH | 0.00006396 | ||||
Handle Ops | 12571752 | 9 days ago | IN | 0 ETH | 0.00001128 | ||||
Handle Ops | 12571752 | 9 days ago | IN | 0 ETH | 0.00003447 | ||||
Handle Ops | 12540573 | 10 days ago | IN | 0 ETH | 0.00000852 | ||||
Handle Ops | 12540573 | 10 days ago | IN | 0 ETH | 0.00002549 | ||||
Handle Ops | 12515702 | 11 days ago | IN | 0 ETH | 0.00000702 | ||||
Handle Ops | 12515701 | 11 days ago | IN | 0 ETH | 0.00003521 | ||||
Handle Ops | 12510659 | 11 days ago | IN | 0 ETH | 0.00000487 | ||||
Handle Ops | 12510659 | 11 days ago | IN | 0 ETH | 0.00003192 | ||||
Handle Ops | 12433193 | 15 days ago | IN | 0 ETH | 0.00000858 | ||||
Handle Ops | 12433192 | 15 days ago | IN | 0 ETH | 0.00000822 | ||||
Handle Ops | 12433192 | 15 days ago | IN | 0 ETH | 0.00001177 | ||||
Handle Ops | 12410073 | 16 days ago | IN | 0 ETH | 0.00001932 | ||||
Handle Ops | 12410036 | 16 days ago | IN | 0 ETH | 0.00000774 | ||||
Handle Ops | 12410035 | 16 days ago | IN | 0 ETH | 0.00001128 | ||||
Handle Ops | 12392251 | 16 days ago | IN | 0 ETH | 0.00004537 | ||||
Handle Ops | 12392251 | 16 days ago | IN | 0 ETH | 0.00006971 | ||||
Handle Ops | 12377012 | 17 days ago | IN | 0 ETH | 0.00002415 | ||||
Handle Ops | 12377011 | 17 days ago | IN | 0 ETH | 0.00003792 | ||||
Handle Ops | 12376985 | 17 days ago | IN | 0 ETH | 0.00002258 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
12572242 | 9 days ago | 0.00001393 ETH | ||||
12572210 | 9 days ago | 0.00001388 ETH | ||||
12572162 | 9 days ago | 0.00001076 ETH | ||||
12571752 | 9 days ago | 0.00002742 ETH | ||||
12556587 | 10 days ago | 0.01 ETH | ||||
12556107 | 10 days ago | 0.01 ETH | ||||
12540573 | 10 days ago | 0.00002489 ETH | ||||
12515701 | 11 days ago | 0.0000439 ETH | ||||
12510659 | 11 days ago | 0.0000304 ETH | ||||
12433192 | 15 days ago | 0.00000976 ETH | ||||
12421639 | 15 days ago | 0.01 ETH | ||||
12410073 | 16 days ago | 0.00001667 ETH | ||||
12410035 | 16 days ago | 0.00000974 ETH | ||||
12392251 | 16 days ago | 0.00003494 ETH | ||||
12377011 | 17 days ago | 0.00001917 ETH | ||||
12376985 | 17 days ago | 0.00001157 ETH | ||||
12202949 | 24 days ago | 0.05 ETH | ||||
12151908 | 26 days ago | 0.00000786 ETH | ||||
12125841 | 27 days ago | 0.00000913 ETH | ||||
12048523 | 30 days ago | 0.00001618 ETH | ||||
12048523 | 30 days ago | 0.00001618 ETH | ||||
12048523 | 30 days ago | 0.00000874 ETH | ||||
12048522 | 30 days ago | 0.00001618 ETH | ||||
12048522 | 30 days ago | 0.00002363 ETH | ||||
12048521 | 30 days ago | 0.00000874 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
EntryPoint
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.23; /* solhint-disable avoid-low-level-calls */ /* solhint-disable no-inline-assembly */ import "../interfaces/IAccount.sol"; import "../interfaces/IAccountExecute.sol"; import "../interfaces/IPaymaster.sol"; import "../interfaces/IEntryPoint.sol"; import "../utils/Exec.sol"; import "./StakeManager.sol"; import "./SenderCreator.sol"; import "./Helpers.sol"; import "./NonceManager.sol"; import "./UserOperationLib.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; /* * Account-Abstraction (EIP-4337) singleton EntryPoint implementation. * Only one instance required on each chain. */ /// @custom:security-contact https://bounty.ethereum.org contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard, ERC165 { using UserOperationLib for PackedUserOperation; SenderCreator private immutable _senderCreator = new SenderCreator(); function senderCreator() internal view virtual returns (SenderCreator) { return _senderCreator; } //compensate for innerHandleOps' emit message and deposit refund. // allow some slack for future gas price changes. uint256 private constant INNER_GAS_OVERHEAD = 10000; // Marker for inner call revert on out of gas bytes32 private constant INNER_OUT_OF_GAS = hex"deaddead"; bytes32 private constant INNER_REVERT_LOW_PREFUND = hex"deadaa51"; uint256 private constant REVERT_REASON_MAX_LEN = 2048; uint256 private constant PENALTY_PERCENT = 10; /// @inheritdoc IERC165 function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // note: solidity "type(IEntryPoint).interfaceId" is without inherited methods but we want to check everything return interfaceId == (type(IEntryPoint).interfaceId ^ type(IStakeManager).interfaceId ^ type(INonceManager).interfaceId) || interfaceId == type(IEntryPoint).interfaceId || interfaceId == type(IStakeManager).interfaceId || interfaceId == type(INonceManager).interfaceId || super.supportsInterface(interfaceId); } /** * 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 operation. * @param opIndex - Index 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, PackedUserOperation calldata userOp, UserOpInfo memory opInfo) internal returns (uint256 collected) { uint256 preGas = gasleft(); bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset); bool success; { uint256 saveFreePtr; assembly ("memory-safe") { saveFreePtr := mload(0x40) } bytes calldata callData = userOp.callData; bytes memory innerCall; bytes4 methodSig; assembly { let len := callData.length if gt(len, 3) { methodSig := calldataload(callData.offset) } } if (methodSig == IAccountExecute.executeUserOp.selector) { bytes memory executeUserOp = abi.encodeCall(IAccountExecute.executeUserOp, (userOp, opInfo.userOpHash)); innerCall = abi.encodeCall(this.innerHandleOp, (executeUserOp, opInfo, context)); } else { innerCall = abi.encodeCall(this.innerHandleOp, (callData, opInfo, context)); } assembly ("memory-safe") { success := call(gas(), address(), 0, add(innerCall, 0x20), mload(innerCall), 0, 32) collected := mload(0) mstore(0x40, saveFreePtr) } } if (!success) { bytes32 innerRevertCode; assembly ("memory-safe") { let len := returndatasize() if eq(32, len) { returndatacopy(0, 0, 32) innerRevertCode := mload(0) } } if (innerRevertCode == INNER_OUT_OF_GAS) { // handleOps was called with gas limit too low. abort entire bundle. //can only be caused by bundler (leaving not enough gas for inner call) revert FailedOp(opIndex, "AA95 out of gas"); } else if (innerRevertCode == INNER_REVERT_LOW_PREFUND) { // innerCall reverted on prefund too low. treat entire prefund as "gas cost" uint256 actualGas = preGas - gasleft() + opInfo.preOpGas; uint256 actualGasCost = opInfo.prefund; emitPrefundTooLow(opInfo); emitUserOperationEvent(opInfo, false, actualGasCost, actualGas); collected = actualGasCost; } else { emit PostOpRevertReason( opInfo.userOpHash, opInfo.mUserOp.sender, opInfo.mUserOp.nonce, Exec.getReturnData(REVERT_REASON_MAX_LEN) ); uint256 actualGas = preGas - gasleft() + opInfo.preOpGas; collected = _postExecution(IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas); } } } function emitUserOperationEvent(UserOpInfo memory opInfo, bool success, uint256 actualGasCost, uint256 actualGas) internal virtual { emit UserOperationEvent( opInfo.userOpHash, opInfo.mUserOp.sender, opInfo.mUserOp.paymaster, opInfo.mUserOp.nonce, success, actualGasCost, actualGas ); } function emitPrefundTooLow(UserOpInfo memory opInfo) internal virtual { emit UserOperationPrefundTooLow(opInfo.userOpHash, opInfo.mUserOp.sender, opInfo.mUserOp.nonce); } /// @inheritdoc IEntryPoint function handleOps(PackedUserOperation[] calldata ops, address payable beneficiary) public nonReentrant { uint256 opslen = ops.length; UserOpInfo[] memory opInfos = new UserOpInfo[](opslen); unchecked { for (uint256 i = 0; i < opslen; i++) { UserOpInfo memory opInfo = opInfos[i]; (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo); _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0)); } uint256 collected = 0; emit BeforeExecution(); for (uint256 i = 0; i < opslen; i++) { collected += _executeUserOp(i, ops[i], opInfos[i]); } _compensate(beneficiary, collected); } } /// @inheritdoc IEntryPoint function handleAggregatedOps(UserOpsPerAggregator[] calldata opsPerAggregator, address payable beneficiary) public nonReentrant { uint256 opasLen = opsPerAggregator.length; uint256 totalOps = 0; for (uint256 i = 0; i < opasLen; i++) { UserOpsPerAggregator calldata opa = opsPerAggregator[i]; PackedUserOperation[] calldata ops = opa.userOps; IAggregator aggregator = opa.aggregator; //address(1) is special marker of "signature error" require(address(aggregator) != address(1), "AA96 invalid aggregator"); if (address(aggregator) != address(0)) { // solhint-disable-next-line no-empty-blocks try aggregator.validateSignatures(ops, opa.signature) {} catch { revert SignatureValidationFailed(address(aggregator)); } } totalOps += ops.length; } UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps); uint256 opIndex = 0; for (uint256 a = 0; a < opasLen; a++) { UserOpsPerAggregator calldata opa = opsPerAggregator[a]; PackedUserOperation[] 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 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo); _validateAccountAndPaymasterValidationData( i, validationData, paymasterValidationData, address(aggregator) ); opIndex++; } } emit BeforeExecution(); uint256 collected = 0; opIndex = 0; for (uint256 a = 0; a < opasLen; a++) { UserOpsPerAggregator calldata opa = opsPerAggregator[a]; emit SignatureAggregatorChanged(address(opa.aggregator)); PackedUserOperation[] 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); } /** * A memory copy of UserOp static fields only. * Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster. */ struct MemoryUserOp { address sender; uint256 nonce; uint256 verificationGasLimit; uint256 callGasLimit; uint256 paymasterVerificationGasLimit; uint256 paymasterPostOpGasLimit; 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. * @param callData - The callData to execute. * @param opInfo - The UserOpInfo struct. * @param context - The context bytes. * @return actualGasCost - the actual cost in eth this UserOperation paid for gas */ function innerHandleOp(bytes memory 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; uint256 callGasLimit = mUserOp.callGasLimit; unchecked { // handleOps was called with gas limit too low. abort entire bundle. if (gasleft() * 63 / 64 < callGasLimit + mUserOp.paymasterPostOpGasLimit + INNER_GAS_OVERHEAD) { assembly ("memory-safe") { mstore(0, INNER_OUT_OF_GAS) revert(0, 32) } } } IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded; if (callData.length > 0) { bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit); if (!success) { bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN); if (result.length > 0) { emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result); } mode = IPaymaster.PostOpMode.opReverted; } } unchecked { uint256 actualGas = preGas - gasleft() + opInfo.preOpGas; return _postExecution(mode, opInfo, context, actualGas); } } /// @inheritdoc IEntryPoint function getUserOpHash(PackedUserOperation 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. * @param userOp - The user operation. * @param mUserOp - The memory user operation. */ function _copyUserOpToMemory(PackedUserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure { mUserOp.sender = userOp.sender; mUserOp.nonce = userOp.nonce; (mUserOp.verificationGasLimit, mUserOp.callGasLimit) = UserOperationLib.unpackUints(userOp.accountGasLimits); mUserOp.preVerificationGas = userOp.preVerificationGas; (mUserOp.maxPriorityFeePerGas, mUserOp.maxFeePerGas) = UserOperationLib.unpackUints(userOp.gasFees); bytes calldata paymasterAndData = userOp.paymasterAndData; if (paymasterAndData.length > 0) { require(paymasterAndData.length >= UserOperationLib.PAYMASTER_DATA_OFFSET, "AA93 invalid paymasterAndData"); (mUserOp.paymaster, mUserOp.paymasterVerificationGasLimit, mUserOp.paymasterPostOpGasLimit) = UserOperationLib.unpackPaymasterStaticFields(paymasterAndData); } else { mUserOp.paymaster = address(0); mUserOp.paymasterVerificationGasLimit = 0; mUserOp.paymasterPostOpGasLimit = 0; } } /** * Get the required prefunded gas fee amount for an operation. * @param mUserOp - The user operation in memory. */ function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) { unchecked { uint256 requiredGas = mUserOp.verificationGasLimit + mUserOp.callGasLimit + mUserOp.paymasterVerificationGasLimit + mUserOp.paymasterPostOpGasLimit + mUserOp.preVerificationGas; requiredPrefund = requiredGas * mUserOp.maxFeePerGas; } } /** * Create sender smart contract account if init code is provided. * @param opIndex - The operation index. * @param opInfo - The operation info. * @param initCode - The init code for the smart contract account. */ 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, "AA10 sender already constructed"); } address sender1 = senderCreator().createSender{gas: opInfo.mUserOp.verificationGasLimit}(initCode); if (sender1 == address(0)) { revert FailedOp(opIndex, "AA13 initCode failed or OOG"); } if (sender1 != sender) { revert FailedOp(opIndex, "AA14 initCode must return sender"); } if (sender1.code.length == 0) { revert FailedOp(opIndex, "AA15 initCode must create sender"); } address factory = address(bytes20(initCode[0:20])); emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster); } } /// @inheritdoc IEntryPoint function getSenderAddress(bytes calldata initCode) public { address sender = senderCreator().createSender(initCode); revert SenderAddressResult(sender); } /** * Call account.validateUserOp. * Revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund. * Decrement account's deposit if needed. * @param opIndex - The operation index. * @param op - The user operation. * @param opInfo - The operation info. * @param requiredPrefund - The required prefund amount. */ function _validateAccountPrepayment( uint256 opIndex, PackedUserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund, uint256 verificationGasLimit ) internal returns (uint256 validationData) { unchecked { MemoryUserOp memory mUserOp = opInfo.mUserOp; address sender = mUserOp.sender; _createSenderIfNeeded(opIndex, opInfo, op.initCode); address paymaster = mUserOp.paymaster; uint256 missingAccountFunds = 0; if (paymaster == address(0)) { uint256 bal = balanceOf(sender); missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal; } try IAccount(sender).validateUserOp{gas: verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds) returns (uint256 _validationData) { validationData = _validationData; } catch { revert FailedOpWithRevert(opIndex, "AA23 reverted", Exec.getReturnData(REVERT_REASON_MAX_LEN)); } if (paymaster == address(0)) { DepositInfo storage senderInfo = deposits[sender]; uint256 deposit = senderInfo.deposit; if (requiredPrefund > deposit) { revert FailedOp(opIndex, "AA21 didn't pay prefund"); } senderInfo.deposit = deposit - requiredPrefund; } } } /** * In case the request has a paymaster: * - Validate paymaster has enough deposit. * - Call paymaster.validatePaymasterUserOp. * - Revert with proper FailedOp in case paymaster reverts. * - Decrement paymaster's deposit. * @param opIndex - The operation index. * @param op - The user operation. * @param opInfo - The operation info. * @param requiredPreFund - The required prefund amount. */ function _validatePaymasterPrepayment( uint256 opIndex, PackedUserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund ) internal returns (bytes memory context, uint256 validationData) { unchecked { uint256 preGas = gasleft(); MemoryUserOp memory mUserOp = opInfo.mUserOp; address paymaster = mUserOp.paymaster; DepositInfo storage paymasterInfo = deposits[paymaster]; uint256 deposit = paymasterInfo.deposit; if (deposit < requiredPreFund) { revert FailedOp(opIndex, "AA31 paymaster deposit too low"); } paymasterInfo.deposit = deposit - requiredPreFund; uint256 pmVerificationGasLimit = mUserOp.paymasterVerificationGasLimit; try IPaymaster(paymaster).validatePaymasterUserOp{gas: pmVerificationGasLimit}( op, opInfo.userOpHash, requiredPreFund ) returns (bytes memory _context, uint256 _validationData) { context = _context; validationData = _validationData; } catch { revert FailedOpWithRevert(opIndex, "AA33 reverted", Exec.getReturnData(REVERT_REASON_MAX_LEN)); } if (preGas - gasleft() > pmVerificationGasLimit) { revert FailedOp(opIndex, "AA36 over paymasterVerificationGasLimit"); } } } /** * Revert if either account validationData or paymaster validationData is expired. * @param opIndex - The operation index. * @param validationData - The account validationData. * @param paymasterValidationData - The paymaster validationData. * @param expectedAggregator - The expected aggregator. */ function _validateAccountAndPaymasterValidationData( uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator ) internal view { (address aggregator, bool outOfTimeRange) = _getValidationData(validationData); if (expectedAggregator != aggregator) { revert FailedOp(opIndex, "AA24 signature error"); } if (outOfTimeRange) { revert FailedOp(opIndex, "AA22 expired or not due"); } // pmAggregator is not a real signature aggregator: we don't have logic to handle it as address. // Non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation). address pmAggregator; (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData); if (pmAggregator != address(0)) { revert FailedOp(opIndex, "AA34 signature error"); } if (outOfTimeRange) { revert FailedOp(opIndex, "AA32 paymaster expired or not due"); } } /** * Parse validationData into its components. * @param validationData - The packed validation data (sigFailed, validAfter, validUntil). * @return aggregator the aggregator of the validationData * @return outOfTimeRange true if current time is outside the time range of this validationData. */ function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) { if (validationData == 0) { return (address(0), false); } ValidationData memory data = _parseValidationData(validationData); // solhint-disable-next-line not-rely-on-time outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter; aggregator = data.aggregator; } /** * Validate account and paymaster (if defined) and * 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, PackedUserOperation calldata userOp, UserOpInfo memory outOpInfo) internal returns (uint256 validationData, uint256 paymasterValidationData) { 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 verificationGasLimit = mUserOp.verificationGasLimit; uint256 maxGasValues = mUserOp.preVerificationGas | verificationGasLimit | mUserOp.callGasLimit | mUserOp.paymasterVerificationGasLimit | mUserOp.paymasterPostOpGasLimit | mUserOp.maxFeePerGas | mUserOp.maxPriorityFeePerGas; require(maxGasValues <= type(uint120).max, "AA94 gas values overflow"); uint256 requiredPreFund = _getRequiredPrefund(mUserOp); validationData = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, verificationGasLimit); if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) { revert FailedOp(opIndex, "AA25 invalid account nonce"); } unchecked { if (preGas - gasleft() > verificationGasLimit) { revert FailedOp(opIndex, "AA26 over verificationGasLimit"); } } bytes memory context; if (mUserOp.paymaster != address(0)) { (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund); } unchecked { 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 was used in the request). * @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 _postExecution( 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) { try IPaymaster(paymaster).postOp{gas: mUserOp.paymasterPostOpGasLimit}( mode, context, actualGasCost, gasPrice ) { // solhint-disable-next-line no-empty-blocks } catch { bytes memory reason = Exec.getReturnData(REVERT_REASON_MAX_LEN); revert PostOpReverted(reason); } } } } actualGas += preGas - gasleft(); // Calculating a penalty for unused execution gas { uint256 executionGasLimit = mUserOp.callGasLimit + mUserOp.paymasterPostOpGasLimit; uint256 executionGasUsed = actualGas - opInfo.preOpGas; // this check is required for the gas used within EntryPoint and not covered by explicit gas limits if (executionGasLimit > executionGasUsed) { uint256 unusedGas = executionGasLimit - executionGasUsed; uint256 unusedGasPenalty = (unusedGas * PENALTY_PERCENT) / 100; actualGas += unusedGasPenalty; } } actualGasCost = actualGas * gasPrice; uint256 prefund = opInfo.prefund; if (prefund < actualGasCost) { if (mode == IPaymaster.PostOpMode.postOpReverted) { actualGasCost = prefund; emitPrefundTooLow(opInfo); emitUserOperationEvent(opInfo, false, actualGasCost, actualGas); } else { assembly ("memory-safe") { mstore(0, INNER_REVERT_LOW_PREFUND) revert(0, 32) } } } else { uint256 refund = prefund - actualGasCost; _incrementDeposit(refundAddress, refund); bool success = mode == IPaymaster.PostOpMode.opSucceeded; emitUserOperationEvent(opInfo, 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. * @param mUserOp - The userOp to get the gas price from. */ 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); } } /** * The offset of the given bytes in memory. * @param data - The bytes to get the offset of. */ function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) { assembly { offset := data } } /** * The bytes in memory at the given offset. * @param offset - The offset to get the bytes from. */ function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) { assembly ("memory-safe") { data := offset } } /// @inheritdoc IEntryPoint function delegateAndRevert(address target, bytes calldata data) external { (bool success, bytes memory ret) = target.delegatecall(data); revert DelegateAndRevert(success, ret); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.5; import "./PackedUserOperation.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 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 validationData - Packaged ValidationData structure. use `_packValidationData` and * `_unpackValidationData` to encode and decode. * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure, * otherwise, an address of an "authorizer" contract. * <6-byte> validUntil - Last timestamp this operation is valid. 0 for "indefinite" * <6-byte> validAfter - First timestamp this operation is valid * If an account doesn't use time-range, it is enough to * return SIG_VALIDATION_FAILED value (1) for signature failure. * Note that the validation code cannot use block.timestamp (or block.number) directly. */ function validateUserOp( PackedUserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds ) external returns (uint256 validationData); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.5; import "./PackedUserOperation.sol"; interface IAccountExecute { /** * Account may implement this execute method. * passing this methodSig at the beginning of callData will cause the entryPoint to pass the full UserOp (and hash) * to the account. * The account should skip the methodSig, and use the callData (and optionally, other UserOp fields) * * @param userOp - The operation that was just validated. * @param userOpHash - Hash of the user's request data. */ function executeUserOp( PackedUserOperation calldata userOp, bytes32 userOpHash ) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.5; import "./PackedUserOperation.sol"; /** * The interface exposed by a paymaster contract, who agrees to pay the gas for user's operations. * A paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction. */ interface IPaymaster { enum PostOpMode { // User op succeeded. opSucceeded, // User op reverted. Still has to pay for gas. opReverted, // Only used internally in the EntryPoint (cleanup after postOp reverts). Never calling paymaster with this value postOpReverted } /** * Payment validation: check if paymaster agrees to pay. * Must verify sender is the entryPoint. * Revert to reject this request. * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted). * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns. * @param userOp - The user operation. * @param userOpHash - Hash of the user's request data. * @param maxCost - The maximum cost of this transaction (based on maximum gas and gas price from userOp). * @return context - Value to send to a postOp. Zero length to signify postOp is not required. * @return validationData - Signature and time-range of this operation, encoded the same as the return * value of validateUserOperation. * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure, * other values are invalid for paymaster. * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite" * <6-byte> validAfter - first timestamp this operation is valid * Note that the validation code cannot use block.timestamp (or block.number) directly. */ function validatePaymasterUserOp( PackedUserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost ) external returns (bytes memory context, uint256 validationData); /** * Post-operation handler. * Must verify sender is the entryPoint. * @param mode - Enum with the following options: * opSucceeded - User operation succeeded. * opReverted - User op reverted. The paymaster still has to pay for gas. * postOpReverted - never passed in a call to postOp(). * @param context - The context value returned by validatePaymasterUserOp * @param actualGasCost - Actual gas used so far (without this postOp call). * @param actualUserOpFeePerGas - the gas price this UserOp pays. This value is based on the UserOp's maxFeePerGas * and maxPriorityFee (and basefee) * It is not the same as tx.gasprice, which is what the bundler pays. */ function postOp( PostOpMode mode, bytes calldata context, uint256 actualGasCost, uint256 actualUserOpFeePerGas ) external; }
/** ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation. ** Only one instance required on each chain. **/ // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.5; /* solhint-disable avoid-low-level-calls */ /* solhint-disable no-inline-assembly */ /* solhint-disable reason-string */ import "./PackedUserOperation.sol"; import "./IStakeManager.sol"; import "./IAggregator.sol"; import "./INonceManager.sol"; interface IEntryPoint is IStakeManager, INonceManager { /*** * An event emitted after each successful request. * @param userOpHash - Unique identifier for the request (hash its entire content, except signature). * @param sender - The account that generates this request. * @param paymaster - If non-null, the paymaster that pays for this request. * @param nonce - The nonce value from the request. * @param success - True if the sender transaction succeeded, false if reverted. * @param actualGasCost - Actual amount paid (by account or paymaster) for this UserOperation. * @param actualGasUsed - Total gas used by this UserOperation (including preVerification, creation, * validation and execution). */ event UserOperationEvent( bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed ); /** * Account "sender" was deployed. * @param userOpHash - The userOp that deployed this account. UserOperationEvent will follow. * @param sender - The account that is deployed * @param factory - The factory used to deploy this account (in the initCode) * @param paymaster - The paymaster used by this UserOp */ event AccountDeployed( bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster ); /** * An event emitted if the UserOperation "callData" reverted with non-zero length. * @param userOpHash - The request unique identifier. * @param sender - The sender of this request. * @param nonce - The nonce used in the request. * @param revertReason - The return bytes from the (reverted) call to "callData". */ event UserOperationRevertReason( bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason ); /** * An event emitted if the UserOperation Paymaster's "postOp" call 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 PostOpRevertReason( bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason ); /** * UserOp consumed more than prefund. The UserOperation is reverted, and no refund is made. * @param userOpHash - The request unique identifier. * @param sender - The sender of this request. * @param nonce - The nonce used in the request. */ event UserOperationPrefundTooLow( bytes32 indexed userOpHash, address indexed sender, uint256 nonce ); /** * An event emitted by handleOps(), before starting the execution loop. * Any event emitted before this event, is part of the validation. */ event BeforeExecution(); /** * Signature aggregator used by the following UserOperationEvents within this bundle. * @param aggregator - The aggregator used for the following UserOperationEvents. */ event SignatureAggregatorChanged(address indexed aggregator); /** * A custom revert error of handleOps, to identify the offending op. * Should be caught in off-chain handleOps simulation and not happen on-chain. * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts. * NOTE: If simulateValidation passes successfully, there should be no reason for handleOps to fail on it. * @param opIndex - Index into the array of ops to the failed one (in simulateValidation, this is always zero). * @param reason - Revert reason. The string starts with a unique code "AAmn", * where "m" is "1" for factory, "2" for account and "3" for paymaster issues, * so a failure can be attributed to the correct entity. */ error FailedOp(uint256 opIndex, string reason); /** * A custom revert error of handleOps, to report a revert by account or paymaster. * @param opIndex - Index into the array of ops to the failed one (in simulateValidation, this is always zero). * @param reason - Revert reason. see FailedOp(uint256,string), above * @param inner - data from inner cought revert reason * @dev note that inner is truncated to 2048 bytes */ error FailedOpWithRevert(uint256 opIndex, string reason, bytes inner); error PostOpReverted(bytes returnData); /** * Error case when a signature aggregator fails to verify the aggregated signature it had created. * @param aggregator The aggregator that failed to verify the signature */ error SignatureValidationFailed(address aggregator); // Return value of getSenderAddress. error SenderAddressResult(address sender); // UserOps handled, per aggregator. struct UserOpsPerAggregator { PackedUserOperation[] userOps; // Aggregator address IAggregator aggregator; // Aggregated signature bytes signature; } /** * Execute a batch of UserOperations. * No signature aggregator is used. * If any account requires an aggregator (that is, it returned an aggregator when * performing simulateValidation), then handleAggregatedOps() must be used instead. * @param ops - The operations to execute. * @param beneficiary - The address to receive the fees. */ function handleOps( PackedUserOperation[] 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. * @param userOp - The user operation to generate the request ID for. * @return hash the hash of this UserOperation */ function getUserOpHash( PackedUserOperation calldata userOp ) external view returns (bytes32); /** * Gas and return values during simulation. * @param preOpGas - The gas used for validation (including preValidationGas) * @param prefund - The required prefund for this operation * @param accountValidationData - returned validationData from account. * @param paymasterValidationData - return validationData from paymaster. * @param paymasterContext - Returned by validatePaymasterUserOp (to be passed into postOp) */ struct ReturnInfo { uint256 preOpGas; uint256 prefund; uint256 accountValidationData; uint256 paymasterValidationData; bytes paymasterContext; } /** * Returned aggregated signature info: * The aggregator returned by the account, and its current stake. */ struct AggregatorStakeInfo { address aggregator; StakeInfo stakeInfo; } /** * Get counterfactual sender address. * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. * This method always revert, and returns the address in SenderAddressResult error * @param initCode - The constructor code to be passed into the UserOperation. */ function getSenderAddress(bytes memory initCode) external; error DelegateAndRevert(bool success, bytes ret); /** * Helper method for dry-run testing. * @dev calling this method, the EntryPoint will make a delegatecall to the given data, and report (via revert) the result. * The method always revert, so is only useful off-chain for dry run calls, in cases where state-override to replace * actual EntryPoint code is less convenient. * @param target a target contract to make a delegatecall from entrypoint * @param data data to pass to target in a delegatecall */ function delegateAndRevert(address target, bytes calldata data) external; }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.23; // solhint-disable no-inline-assembly /** * Utility functions helpful when making different kinds of contract calls in Solidity. */ library Exec { function call( address to, uint256 value, bytes memory data, uint256 txGas ) internal returns (bool success) { assembly ("memory-safe") { success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0) } } function staticcall( address to, bytes memory data, uint256 txGas ) internal view returns (bool success) { assembly ("memory-safe") { success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0) } } function delegateCall( address to, bytes memory data, uint256 txGas ) internal returns (bool success) { assembly ("memory-safe") { success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0) } } // get returned data from last call or calldelegate function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) { assembly ("memory-safe") { let len := returndatasize() if gt(len, maxLen) { len := maxLen } let ptr := mload(0x40) mstore(0x40, add(ptr, add(len, 0x20))) mstore(ptr, len) returndatacopy(add(ptr, 0x20), 0, len) returnData := ptr } } // revert with explicit byte array (probably reverted info from call) function revertWithData(bytes memory returnData) internal pure { assembly ("memory-safe") { revert(add(returnData, 32), mload(returnData)) } } function callAndRevert(address to, bytes memory data, uint256 maxLen) internal { bool success = call(to,0,data,gasleft()); if (!success) { revertWithData(getReturnData(maxLen)); } } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.23; 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; /// @inheritdoc IStakeManager function getDepositInfo( address account ) public view returns (DepositInfo memory info) { return deposits[account]; } /** * Internal method to return just the stake info. * @param addr - The account to query. */ function _getStakeInfo( address addr ) internal view returns (StakeInfo memory info) { DepositInfo storage depositInfo = deposits[addr]; info.stake = depositInfo.stake; info.unstakeDelaySec = depositInfo.unstakeDelaySec; } /// @inheritdoc IStakeManager function balanceOf(address account) public view returns (uint256) { return deposits[account].deposit; } receive() external payable { depositTo(msg.sender); } /** * Increments an account's deposit. * @param account - The account to increment. * @param amount - The amount to increment by. * @return the updated deposit of this account */ function _incrementDeposit(address account, uint256 amount) internal returns (uint256) { DepositInfo storage info = deposits[account]; uint256 newAmount = info.deposit + amount; info.deposit = newAmount; return newAmount; } /** * Add to the deposit of the given account. * @param account - The account to add to. */ function depositTo(address account) public virtual payable { uint256 newDeposit = _incrementDeposit(account, msg.value); emit Deposited(account, newDeposit); } /** * 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"); uint48 withdrawTime = uint48(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 = 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.23; /** * 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 factory = address(bytes20(initCode[0:20])); bytes memory initCallData = initCode[20:]; bool success; /* solhint-disable no-inline-assembly */ assembly ("memory-safe") { success := call( gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32 ) sender := mload(0) } if (!success) { sender = address(0); } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.23; /* solhint-disable no-inline-assembly */ /* * For simulation purposes, validateUserOp (and validatePaymasterUserOp) * must return this value in case of signature failure, instead of revert. */ uint256 constant SIG_VALIDATION_FAILED = 1; /* * For simulation purposes, validateUserOp (and validatePaymasterUserOp) * return this value on success. */ uint256 constant SIG_VALIDATION_SUCCESS = 0; /** * Returned data from validateUserOp. * validateUserOp returns a uint256, which is created by `_packedValidationData` and * parsed by `_parseValidationData`. * @param aggregator - address(0) - The account validated the signature by itself. * address(1) - The account failed to validate the signature. * otherwise - This is an address of a signature aggregator that must * be used to validate the signature. * @param validAfter - This UserOp is valid only after this timestamp. * @param validaUntil - This UserOp is valid only up to this timestamp. */ struct ValidationData { address aggregator; uint48 validAfter; uint48 validUntil; } /** * Extract sigFailed, validAfter, validUntil. * Also convert zero validUntil to type(uint48).max. * @param validationData - The packed validation data. */ function _parseValidationData(uint256 validationData) pure returns (ValidationData memory data) { address aggregator = address(uint160(validationData)); uint48 validUntil = uint48(validationData >> 160); if (validUntil == 0) { validUntil = type(uint48).max; } uint48 validAfter = uint48(validationData >> (48 + 160)); return ValidationData(aggregator, validAfter, validUntil); } /** * Helper to pack the return value for validateUserOp. * @param data - The ValidationData to pack. */ function _packValidationData(ValidationData memory data) pure returns (uint256) { return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48)); } /** * Helper to pack the return value for validateUserOp, when not using an aggregator. * @param sigFailed - True for signature failure, false for success. * @param validUntil - Last timestamp this UserOperation is valid (or zero for infinite). * @param validAfter - First timestamp this UserOperation is valid. */ function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) { return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48)); } /** * keccak function over calldata. * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it. */ function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) { assembly ("memory-safe") { let mem := mload(0x40) let len := data.length calldatacopy(mem, data.offset, len) ret := keccak256(mem, len) } } /** * The minimum of two numbers. * @param a - First number. * @param b - Second number. */ function min(uint256 a, uint256 b) pure returns (uint256) { return a < b ? a : b; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.23; import "../interfaces/INonceManager.sol"; /** * nonce management functionality */ abstract contract NonceManager is INonceManager { /** * The next valid sequence number for a given nonce key. */ mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber; /// @inheritdoc INonceManager function getNonce(address sender, uint192 key) public view override returns (uint256 nonce) { return nonceSequenceNumber[sender][key] | (uint256(key) << 64); } // allow an account to manually increment its own nonce. // (mainly so that during construction nonce can be made non-zero, // to "absorb" the gas cost of first nonce increment to 1st transaction (construction), // not to 2nd transaction) function incrementNonce(uint192 key) public override { nonceSequenceNumber[msg.sender][key]++; } /** * validate nonce uniqueness for this account. * called just after validateUserOp() * @return true if the nonce was incremented successfully. * false if the current nonce doesn't match the given one. */ function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) { uint192 key = uint192(nonce >> 64); uint64 seq = uint64(nonce); return nonceSequenceNumber[sender][key]++ == seq; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.23; /* solhint-disable no-inline-assembly */ import "../interfaces/PackedUserOperation.sol"; import {calldataKeccak, min} from "./Helpers.sol"; /** * Utility functions helpful when working with UserOperation structs. */ library UserOperationLib { uint256 public constant PAYMASTER_VALIDATION_GAS_OFFSET = 20; uint256 public constant PAYMASTER_POSTOP_GAS_OFFSET = 36; uint256 public constant PAYMASTER_DATA_OFFSET = 52; /** * Get sender from user operation data. * @param userOp - The user operation data. */ function getSender( PackedUserOperation calldata userOp ) internal pure returns (address) { address data; //read sender from userOp, which is first userOp member (saves 800 gas...) assembly { data := calldataload(userOp) } return address(uint160(data)); } /** * Relayer/block builder might submit the TX with higher priorityFee, * but the user should not pay above what he signed for. * @param userOp - The user operation data. */ function gasPrice( PackedUserOperation calldata userOp ) internal view returns (uint256) { unchecked { (uint256 maxPriorityFeePerGas, uint256 maxFeePerGas) = unpackUints(userOp.gasFees); if (maxFeePerGas == maxPriorityFeePerGas) { //legacy mode (for networks that don't support basefee opcode) return maxFeePerGas; } return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee); } } /** * Pack the user operation data into bytes for hashing. * @param userOp - The user operation data. */ function encode( PackedUserOperation calldata userOp ) internal pure returns (bytes memory ret) { address sender = getSender(userOp); uint256 nonce = userOp.nonce; bytes32 hashInitCode = calldataKeccak(userOp.initCode); bytes32 hashCallData = calldataKeccak(userOp.callData); bytes32 accountGasLimits = userOp.accountGasLimits; uint256 preVerificationGas = userOp.preVerificationGas; bytes32 gasFees = userOp.gasFees; bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData); return abi.encode( sender, nonce, hashInitCode, hashCallData, accountGasLimits, preVerificationGas, gasFees, hashPaymasterAndData ); } function unpackUints( bytes32 packed ) internal pure returns (uint256 high128, uint256 low128) { return (uint128(bytes16(packed)), uint128(uint256(packed))); } //unpack just the high 128-bits from a packed value function unpackHigh128(bytes32 packed) internal pure returns (uint256) { return uint256(packed) >> 128; } // unpack just the low 128-bits from a packed value function unpackLow128(bytes32 packed) internal pure returns (uint256) { return uint128(uint256(packed)); } function unpackMaxPriorityFeePerGas(PackedUserOperation calldata userOp) internal pure returns (uint256) { return unpackHigh128(userOp.gasFees); } function unpackMaxFeePerGas(PackedUserOperation calldata userOp) internal pure returns (uint256) { return unpackLow128(userOp.gasFees); } function unpackVerificationGasLimit(PackedUserOperation calldata userOp) internal pure returns (uint256) { return unpackHigh128(userOp.accountGasLimits); } function unpackCallGasLimit(PackedUserOperation calldata userOp) internal pure returns (uint256) { return unpackLow128(userOp.accountGasLimits); } function unpackPaymasterVerificationGasLimit(PackedUserOperation calldata userOp) internal pure returns (uint256) { return uint128(bytes16(userOp.paymasterAndData[PAYMASTER_VALIDATION_GAS_OFFSET : PAYMASTER_POSTOP_GAS_OFFSET])); } function unpackPostOpGasLimit(PackedUserOperation calldata userOp) internal pure returns (uint256) { return uint128(bytes16(userOp.paymasterAndData[PAYMASTER_POSTOP_GAS_OFFSET : PAYMASTER_DATA_OFFSET])); } function unpackPaymasterStaticFields( bytes calldata paymasterAndData ) internal pure returns (address paymaster, uint256 validationGasLimit, uint256 postOpGasLimit) { return ( address(bytes20(paymasterAndData[: PAYMASTER_VALIDATION_GAS_OFFSET])), uint128(bytes16(paymasterAndData[PAYMASTER_VALIDATION_GAS_OFFSET : PAYMASTER_POSTOP_GAS_OFFSET])), uint128(bytes16(paymasterAndData[PAYMASTER_POSTOP_GAS_OFFSET : PAYMASTER_DATA_OFFSET])) ); } /** * Hash the user operation data. * @param userOp - The user operation data. */ function hash( PackedUserOperation calldata userOp ) internal pure returns (bytes32) { return keccak256(encode(userOp)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.5; /** * 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 accountGasLimits - Packed gas limits for validateUserOp and gas limit passed to the callData method call. * @param preVerificationGas - Gas not calculated by the handleOps method, but added to the gas paid. * Covers batch overhead. * @param gasFees - packed gas fields maxPriorityFeePerGas and maxFeePerGas - Same as EIP-1559 gas parameters. * @param paymasterAndData - If set, this field holds the paymaster address, verification gas limit, postOp gas limit and paymaster-specific extra 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 PackedUserOperation { address sender; uint256 nonce; bytes initCode; bytes callData; bytes32 accountGasLimits; uint256 preVerificationGas; bytes32 gasFees; bytes paymasterAndData; bytes signature; }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.7.5; /** * Manage deposits and stakes. * Deposit is just a balance used to pay for UserOperations (either by a paymaster or an account). * Stake is value locked for at least "unstakeDelay" by the staked entity. */ interface IStakeManager { event Deposited(address indexed account, uint256 totalDeposit); event Withdrawn( address indexed account, address withdrawAddress, uint256 amount ); // Emitted when stake or unstake delay are modified. event StakeLocked( address indexed account, uint256 totalStaked, uint256 unstakeDelaySec ); // Emitted once a stake is scheduled for withdrawal. event StakeUnlocked(address indexed account, uint256 withdrawTime); event StakeWithdrawn( address indexed account, address withdrawAddress, uint256 amount ); /** * @param deposit - The entity's deposit. * @param staked - True if this entity is staked. * @param stake - Actual amount of ether staked for this entity. * @param unstakeDelaySec - Minimum delay to withdraw the stake. * @param withdrawTime - First block timestamp where 'withdrawStake' will be callable, or zero if already locked. * @dev Sizes were chosen so that deposit fits into one cell (used during handleOp) * and the rest fit into a 2nd cell (used during stake/unstake) * - 112 bit allows for 10^15 eth * - 48 bit for full timestamp * - 32 bit allows 150 years for unstake delay */ struct DepositInfo { uint256 deposit; bool staked; uint112 stake; uint32 unstakeDelaySec; uint48 withdrawTime; } // API struct used by getStakeInfo and simulateValidation. struct StakeInfo { uint256 stake; uint256 unstakeDelaySec; } /** * Get deposit info. * @param account - The account to query. * @return info - Full deposit information of given account. */ function getDepositInfo( address account ) external view returns (DepositInfo memory info); /** * Get account balance. * @param account - The account to query. * @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. * @param account - The account to add to. */ 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.7.5; import "./PackedUserOperation.sol"; /** * Aggregated Signatures validator. */ interface IAggregator { /** * Validate aggregated signature. * Revert if the aggregated signature does not match the given list of operations. * @param userOps - Array of UserOperations to validate the signature for. * @param signature - The aggregated signature. */ function validateSignatures( PackedUserOperation[] calldata userOps, bytes calldata signature ) external view; /** * Validate signature of a single userOp. * This method should be called by bundler after EntryPointSimulation.simulateValidation() returns * the aggregator this account uses. * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps. * @param userOp - The userOperation received from the user. * @return sigForUserOp - The value to put into the signature field of the userOp when calling handleOps. * (usually empty, unless account and aggregator support some kind of "multisig". */ function validateUserOpSignature( PackedUserOperation calldata userOp ) external view returns (bytes memory sigForUserOp); /** * Aggregate multiple signatures into a single value. * This method is called off-chain to calculate the signature to pass with handleOps() * bundler MAY use optimized custom code perform this aggregation. * @param userOps - Array of UserOperations to collect the signatures from. * @return aggregatedSignature - The aggregated signature. */ function aggregateSignatures( PackedUserOperation[] calldata userOps ) external view returns (bytes memory aggregatedSignature); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.5; interface INonceManager { /** * Return the next nonce for this sender. * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) * But UserOp with different keys can come with arbitrary order. * * @param sender the account address * @param key the high 192 bit of the nonce * @return nonce a full nonce to pass for next UserOp with this sender. */ function getNonce(address sender, uint192 key) external view returns (uint256 nonce); /** * Manually increment the nonce of the sender. * This method is exposed just for completeness.. * Account does NOT need to call it, neither during validation, nor elsewhere, * as the EntryPoint will update the nonce regardless. * Possible use-case is call it with various keys to "initialize" their nonces to one, so that future * UserOperations will not pay extra for the first transaction with a given key. */ function incrementNonce(uint192 key) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "remappings": [ "forge-std/=lib/forge-std/src/", "@openzeppelin/=lib/@openzeppelin/", "contracts/utils/=src/utils/", "contracts/interfaces/=src/interfaces/", "contracts/core/=src/core/" ], "optimizer": { "enabled": true, "runs": 1000000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "paris", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"ret","type":"bytes"}],"name":"DelegateAndRevert","type":"error"},{"inputs":[{"internalType":"uint256","name":"opIndex","type":"uint256"},{"internalType":"string","name":"reason","type":"string"}],"name":"FailedOp","type":"error"},{"inputs":[{"internalType":"uint256","name":"opIndex","type":"uint256"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"inner","type":"bytes"}],"name":"FailedOpWithRevert","type":"error"},{"inputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"PostOpReverted","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"SenderAddressResult","type":"error"},{"inputs":[{"internalType":"address","name":"aggregator","type":"address"}],"name":"SignatureValidationFailed","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":[],"name":"BeforeExecution","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":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":"PostOpRevertReason","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"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":"unstakeDelaySec","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"}],"name":"UserOperationPrefundTooLow","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":[{"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":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"delegateAndRevert","outputs":[],"stateMutability":"nonpayable","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":"uint256","name":"deposit","type":"uint256"},{"internalType":"bool","name":"staked","type":"bool"},{"internalType":"uint112","name":"stake","type":"uint112"},{"internalType":"uint32","name":"unstakeDelaySec","type":"uint32"},{"internalType":"uint48","name":"withdrawTime","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getDepositInfo","outputs":[{"components":[{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"bool","name":"staked","type":"bool"},{"internalType":"uint112","name":"stake","type":"uint112"},{"internalType":"uint32","name":"unstakeDelaySec","type":"uint32"},{"internalType":"uint48","name":"withdrawTime","type":"uint48"}],"internalType":"struct IStakeManager.DepositInfo","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint192","name":"key","type":"uint192"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"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":"bytes32","name":"accountGasLimits","type":"bytes32"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"bytes32","name":"gasFees","type":"bytes32"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct PackedUserOperation","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":"bytes32","name":"accountGasLimits","type":"bytes32"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"bytes32","name":"gasFees","type":"bytes32"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct PackedUserOperation[]","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":"bytes32","name":"accountGasLimits","type":"bytes32"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"bytes32","name":"gasFees","type":"bytes32"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct PackedUserOperation[]","name":"ops","type":"tuple[]"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"handleOps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint192","name":"key","type":"uint192"}],"name":"incrementNonce","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":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"paymasterVerificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"paymasterPostOpGasLimit","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":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint192","name":"","type":"uint192"}],"name":"nonceSequenceNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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
60a08060405234620000825760016002556101df8181016001600160401b038111838210176200006c57829162003f2b833903906000f080156200006057608052604051613ea39081620000888239608051818181610d22015261324b0152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610024575b361561001957600080fd5b61002233612748565b005b60003560e01c806242dc5314611b0057806301ffc9a7146119ae5780630396cb60146116765780630bd28e3b146115fa5780631b2e01b814611566578063205c2878146113d157806322cdde4c1461136b57806335567e1a146112b35780635287ce12146111a557806370a0823114611140578063765e827f14610e82578063850aaf6214610dc35780639b249f6914610c74578063b760faf914610c3a578063bb9fe6bf14610a68578063c23a5cea146107c4578063dbed18e0146101a15763fc7e286d0361000e573461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61013a61229f565b16600052600060205260a0604060002065ffffffffffff6001825492015460405192835260ff8116151560208401526dffffffffffffffffffffffffffff8160081c16604084015263ffffffff8160781c16606084015260981c166080820152f35b600080fd5b3461019c576101af36612317565b906101b86129bd565b60009160005b82811061056f57506101d08493612588565b6000805b8481106102fc5750507fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000809360005b81811061024757610240868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2613ba7565b6001600255005b6102a261025582848a612796565b73ffffffffffffffffffffffffffffffffffffffff6102766020830161282a565b167f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a2806127d6565b906000915b8083106102b957505050600101610209565b909194976102f36102ed6001926102e78c8b6102e0826102da8e8b8d61269d565b9261265a565b5191613597565b90612409565b99612416565b950191906102a7565b6020610309828789612796565b61031f61031682806127d6565b9390920161282a565b9160009273ffffffffffffffffffffffffffffffffffffffff8091165b8285106103505750505050506001016101d4565b909192939561037f83610378610366848c61265a565b516103728b898b61269d565b856129f6565b9290613dd7565b9116840361050a576104a5576103958491613dd7565b9116610440576103b5576103aa600191612416565b96019392919061033c565b60a487604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608489604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b61057a818487612796565b9361058585806127d6565b919095602073ffffffffffffffffffffffffffffffffffffffff6105aa82840161282a565b1697600192838a1461076657896105da575b5050505060019293949550906105d191612409565b939291016101be565b8060406105e892019061284b565b918a3b1561019c57929391906040519485937f2dd8113300000000000000000000000000000000000000000000000000000000855288604486016040600488015252606490818601918a60051b8701019680936000915b8c83106106e657505050505050838392610684927ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8560009803016024860152612709565b03818a5afa90816106d7575b506106c657602486604051907f86a9f7500000000000000000000000000000000000000000000000000000000082526004820152fd5b93945084936105d1600189806105bc565b6106e0906121bd565b88610690565b91939596977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c908a9294969a0301865288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181121561019c57836107538793858394016128ec565b9a0196019301909189979695949261063f565b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b3461019c576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576107fc61229f565b33600052600082526001604060002001908154916dffffffffffffffffffffffffffff8360081c16928315610a0a5765ffffffffffff8160981c1680156109ac57421061094e5760009373ffffffffffffffffffffffffffffffffffffffff859485947fffffffffffffff000000000000000000000000000000000000000000000000ff86951690556040517fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda33391806108da8786836020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b0390a2165af16108e8612450565b50156108f057005b606490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b3461019c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c573360005260006020526001604060002001805463ffffffff8160781c16908115610bdc5760ff1615610b7e5765ffffffffffff908142160191818311610b4f5780547fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff001678ffffffffffff00000000000000000000000000000000000000609885901b161790556040519116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a2005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610022610c6f61229f565b612748565b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043567ffffffffffffffff811161019c576020610cc8610d1b9236906004016122c2565b919073ffffffffffffffffffffffffffffffffffffffff9260405194859283927f570e1a360000000000000000000000000000000000000000000000000000000084528560048501526024840191612709565b03816000857f0000000000000000000000000000000000000000000000000000000000000000165af1908115610db757602492600092610d86575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b610da991925060203d602011610db0575b610da181836121ed565b8101906126dd565b9083610d56565b503d610d97565b6040513d6000823e3d90fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610dfa61229f565b60243567ffffffffffffffff811161019c57600091610e1e839236906004016122c2565b90816040519283928337810184815203915af4610e39612450565b90610e7e6040519283927f99410554000000000000000000000000000000000000000000000000000000008452151560048401526040602484015260448301906123c6565b0390fd5b3461019c57610e9036612317565b610e9b9291926129bd565b610ea483612588565b60005b848110610f1c57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000915b858310610eec576102408585613ba7565b909193600190610f12610f0087898761269d565b610f0a888661265a565b519088613597565b0194019190610edb565b610f47610f40610f2e8385979561265a565b51610f3a84898761269d565b846129f6565b9190613dd7565b73ffffffffffffffffffffffffffffffffffffffff929183166110db5761107657610f7190613dd7565b911661101157610f8657600101929092610ea7565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608483604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61118c61229f565b1660005260006020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff6111f161229f565b6000608060405161120181612155565b828152826020820152826040820152826060820152015216600052600060205260a06040600020608060405161123681612155565b6001835493848352015490602081019060ff8316151582526dffffffffffffffffffffffffffff60408201818560081c16815263ffffffff936060840193858760781c16855265ffffffffffff978891019660981c1686526040519788525115156020880152511660408601525116606084015251166080820152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760206112ec61229f565b73ffffffffffffffffffffffffffffffffffffffff6113096122f0565b911660005260018252604060002077ffffffffffffffffffffffffffffffffffffffffffffffff821660005282526040600020547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b3461019c577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60208136011261019c576004359067ffffffffffffffff821161019c5761012090823603011261019c576113c9602091600401612480565b604051908152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761140861229f565b60243590336000526000602052604060002090815491828411611508576000808573ffffffffffffffffffffffffffffffffffffffff8295839561144c848a612443565b90556040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af16114a2612450565b50156114aa57005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761159d61229f565b73ffffffffffffffffffffffffffffffffffffffff6115ba6122f0565b9116600052600160205277ffffffffffffffffffffffffffffffffffffffffffffffff604060002091166000526020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043577ffffffffffffffffffffffffffffffffffffffffffffffff811680910361019c5733600052600160205260406000209060005260205260406000206116728154612416565b9055005b6020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043563ffffffff9182821680920361019c5733600052600081526040600020928215611950576001840154908160781c1683106118f2576116f86dffffffffffffffffffffffffffff9182349160081c16612409565b93841561189457818511611836579065ffffffffffff61180592546040519061172082612155565b8152848101926001845260408201908816815260608201878152600160808401936000855233600052600089526040600020905181550194511515917fffffffffffffffffffffffffff0000000000000000000000000000000000000060ff72ffffffff0000000000000000000000000000006effffffffffffffffffffffffffff008954945160081b16945160781b1694169116171717835551167fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffff78ffffffffffff0000000000000000000000000000000000000083549260981b169116179055565b6040519283528201527fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c0160403392a2005b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361019c57807f60fc6b6e0000000000000000000000000000000000000000000000000000000060209214908115611ad6575b8115611aac575b8115611a82575b8115611a58575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482611a4d565b7f3e84f0210000000000000000000000000000000000000000000000000000000081149150611a46565b7fcf28ef970000000000000000000000000000000000000000000000000000000081149150611a3f565b7f915074d80000000000000000000000000000000000000000000000000000000081149150611a38565b3461019c576102007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5767ffffffffffffffff60043581811161019c573660238201121561019c57611b62903690602481600401359101612268565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101c0811261019c5761014060405191611b9e83612155565b1261019c5760405192611bb0846121a0565b60243573ffffffffffffffffffffffffffffffffffffffff8116810361019c578452602093604435858201526064356040820152608435606082015260a435608082015260c43560a082015260e43560c08201526101043573ffffffffffffffffffffffffffffffffffffffff8116810361019c5760e08201526101243561010082015261014435610120820152825261016435848301526101843560408301526101a43560608301526101c43560808301526101e43590811161019c57611c7c9036906004016122c2565b905a3033036120f7578351606081015195603f5a0260061c61271060a0840151890101116120ce5760009681519182611ff0575b5050505090611cca915a9003608085015101923691612268565b925a90600094845193611cdc85613ccc565b9173ffffffffffffffffffffffffffffffffffffffff60e0870151168015600014611ea957505073ffffffffffffffffffffffffffffffffffffffff855116935b5a9003019360a06060820151910151016080860151850390818111611e95575b50508302604085015192818410600014611dce5750506003811015611da157600203611d79576113c99293508093611d7481613d65565b613cf6565b5050507fdeadaa51000000000000000000000000000000000000000000000000000000008152fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b81611dde92979396940390613c98565b506003841015611e6857507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f60808683015192519473ffffffffffffffffffffffffffffffffffffffff865116948873ffffffffffffffffffffffffffffffffffffffff60e0890151169701519160405192835215898301528760408301526060820152a46113c9565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526021600452fd5b6064919003600a0204909301928780611d3d565b8095918051611eba575b5050611d1d565b6003861015611fc1576002860315611eb35760a088015190823b1561019c57600091611f2491836040519586809581947f7c627b210000000000000000000000000000000000000000000000000000000083528d60048401526080602484015260848301906123c6565b8b8b0260448301528b60648301520393f19081611fad575b50611fa65787893d610800808211611f9e575b506040519282828501016040528184528284013e610e7e6040519283927fad7954bc000000000000000000000000000000000000000000000000000000008452600484015260248301906123c6565b905083611f4f565b8980611eb3565b611fb89199506121bd565b6000978a611f3c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91600092918380938c73ffffffffffffffffffffffffffffffffffffffff885116910192f115612023575b808080611cb0565b611cca929195503d6108008082116120c6575b5060405190888183010160405280825260008983013e805161205f575b5050600194909161201b565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20188870151918973ffffffffffffffffffffffffffffffffffffffff8551169401516120bc604051928392835260408d84015260408301906123c6565b0390a38680612053565b905088612036565b877fdeaddead000000000000000000000000000000000000000000000000000000006000526000fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b60a0810190811067ffffffffffffffff82111761217157604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610140810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157604052565b6060810190811067ffffffffffffffff82111761217157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9291926122748261222e565b9161228260405193846121ed565b82948184528183011161019c578281602093846000960137010152565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9181601f8401121561019c5782359167ffffffffffffffff831161019c576020838186019501011161019c57565b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261019c5760043567ffffffffffffffff9283821161019c578060238301121561019c57816004013593841161019c5760248460051b8301011161019c57602401919060243573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b60005b8381106123b65750506000910152565b81810151838201526020016123a6565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093612402815180928187528780880191016123a3565b0116010190565b91908201809211610b4f57565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610b4f5760010190565b91908203918211610b4f57565b3d1561247b573d906124618261222e565b9161246f60405193846121ed565b82523d6000602084013e565b606090565b604061248e8183018361284b565b90818351918237206124a3606084018461284b565b90818451918237209260c06124bb60e083018361284b565b908186519182372091845195602087019473ffffffffffffffffffffffffffffffffffffffff833516865260208301358789015260608801526080870152608081013560a087015260a081013582870152013560e08501526101009081850152835261012083019167ffffffffffffffff918484108385111761217157838252845190206101408501908152306101608601524661018086015260608452936101a00191821183831017612171575251902090565b67ffffffffffffffff81116121715760051b60200190565b9061259282612570565b6040906125a260405191826121ed565b8381527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06125d08295612570565b019160005b8381106125e25750505050565b60209082516125f081612155565b83516125fb816121a0565b600081526000849181838201528187820152816060818184015260809282848201528260a08201528260c08201528260e082015282610100820152826101208201528652818587015281898701528501528301528286010152016125d5565b805182101561266e5760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b919081101561266e5760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18136030182121561019c570190565b9081602091031261019c575173ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b7f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4602073ffffffffffffffffffffffffffffffffffffffff61278a3485613c98565b936040519485521692a2565b919081101561266e5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18136030182121561019c570190565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c57602001918160051b3603831361019c57565b3573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c5760200191813603831361019c57565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561019c57016020813591019167ffffffffffffffff821161019c57813603831361019c57565b61012091813573ffffffffffffffffffffffffffffffffffffffff811680910361019c576129626129476129ba9561299b93855260208601356020860152612937604087018761289c565b9091806040880152860191612709565b612954606086018661289c565b908583036060870152612709565b6080840135608084015260a084013560a084015260c084013560c084015261298d60e085018561289c565b9084830360e0860152612709565b916129ac610100918281019061289c565b929091818503910152612709565b90565b60028054146129cc5760028055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b926000905a93805194843573ffffffffffffffffffffffffffffffffffffffff811680910361019c5786526020850135602087015260808501356fffffffffffffffffffffffffffffffff90818116606089015260801c604088015260a086013560c088015260c086013590811661010088015260801c610120870152612a8060e086018661284b565b801561357b576034811061351d578060141161019c578060241161019c5760341161019c57602481013560801c60a0880152601481013560801c60808801523560601c60e08701525b612ad285612480565b60208301526040860151946effffffffffffffffffffffffffffff8660c08901511760608901511760808901511760a0890151176101008901511761012089015117116134bf57604087015160608801510160808801510160a08801510160c0880151016101008801510296835173ffffffffffffffffffffffffffffffffffffffff81511690612b66604085018561284b565b806131e4575b505060e0015173ffffffffffffffffffffffffffffffffffffffff1690600082156131ac575b6020612bd7918b828a01516000868a604051978896879586937f19822f7c00000000000000000000000000000000000000000000000000000000855260048501613db5565b0393f160009181613178575b50612c8b573d8c610800808311612c83575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141323320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612bf5565b9a92939495969798999a91156130f2575b509773ffffffffffffffffffffffffffffffffffffffff835116602084015190600052600160205260406000208160401c60005260205267ffffffffffffffff604060002091825492612cee84612416565b9055160361308d575a8503116130285773ffffffffffffffffffffffffffffffffffffffff60e0606093015116612d42575b509060a09184959697986040608096015260608601520135905a900301910152565b969550505a9683519773ffffffffffffffffffffffffffffffffffffffff60e08a01511680600052600060205260406000208054848110612fc3576080612dcd9a9b9c600093878094039055015192602089015183604051809d819582947f52b7512c0000000000000000000000000000000000000000000000000000000084528c60048501613db5565b039286f1978860009160009a612f36575b50612e86573d8b610800808311612e7e575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141333320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612df0565b9991929394959697989998925a900311612eab57509096959094939291906080612d20565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602760448201527f41413336206f766572207061796d6173746572566572696669636174696f6e4760648201527f61734c696d6974000000000000000000000000000000000000000000000000006084820152fd5b915098503d90816000823e612f4b82826121ed565b604081838101031261019c5780519067ffffffffffffffff821161019c57828101601f83830101121561019c578181015191612f868361222e565b93612f9460405195866121ed565b838552820160208483850101011161019c57602092612fba9184808701918501016123a3565b01519838612dde565b60848b604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413331207061796d6173746572206465706f73697420746f6f206c6f7700006064820152fd5b608490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413236206f76657220766572696669636174696f6e4761734c696d697400006064820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601a60448201527f4141323520696e76616c6964206163636f756e74206e6f6e63650000000000006064820152fd5b600052600060205260406000208054808c11613113578b9003905538612c9c565b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152fd5b9091506020813d6020116131a4575b81613194602093836121ed565b8101031261019c57519038612be3565b3d9150613187565b508060005260006020526040600020548a81116000146131d75750612bd7602060005b915050612b92565b6020612bd7918c036131cf565b833b61345a57604088510151602060405180927f570e1a360000000000000000000000000000000000000000000000000000000082528260048301528160008161323260248201898b612709565b039273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690f1908115610db75760009161343b575b5073ffffffffffffffffffffffffffffffffffffffff811680156133d6578503613371573b1561330c5760141161019c5773ffffffffffffffffffffffffffffffffffffffff9183887fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d604060e0958787602086015195510151168251913560601c82526020820152a391612b6c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152fd5b60848e604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313420696e6974436f6465206d7573742072657475726e2073656e6465726064820152fd5b60848f604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601b60448201527f4141313320696e6974436f6465206661696c6564206f72204f4f4700000000006064820152fd5b613454915060203d602011610db057610da181836121ed565b3861327c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b5050600060e087015260006080870152600060a0870152612ac9565b9092915a906060810151916040928351967fffffffff00000000000000000000000000000000000000000000000000000000886135d7606084018461284b565b600060038211613b9f575b7f8dd7712f0000000000000000000000000000000000000000000000000000000094168403613a445750505061379d6000926136b292602088015161363a8a5193849360208501528b602485015260648401906128ec565b90604483015203906136727fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0928381018352826121ed565b61379189519485927e42dc5300000000000000000000000000000000000000000000000000000000602085015261020060248501526102248401906123c6565b613760604484018b60806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152876123c6565b039081018352826121ed565b6020918183809351910182305af1600051988652156137bf575b505050505050565b909192939495965060003d8214613a3a575b7fdeaddead00000000000000000000000000000000000000000000000000000000810361385b57608487878051917f220266b600000000000000000000000000000000000000000000000000000000835260048301526024820152600f60448201527f41413935206f7574206f662067617300000000000000000000000000000000006064820152fd5b7fdeadaa510000000000000000000000000000000000000000000000000000000091929395949650146000146138c55750506138a961389e6138b8935a90612443565b608085015190612409565b9083015183611d748295613d65565b905b3880808080806137b7565b909261395290828601518651907ff62676f440ff169a3a9afdbf812e89e7f95975ee8e5c31214ffdef631c5f479273ffffffffffffffffffffffffffffffffffffffff9580878551169401516139483d610800808211613a32575b508a519084818301018c5280825260008583013e8a805194859485528401528a8301906123c6565b0390a35a90612443565b916139636080860193845190612409565b926000905a94829488519761397789613ccc565b948260e08b0151168015600014613a1857505050875116955b5a9003019560a06060820151910151019051860390818111613a04575b5050840290850151928184106000146139de57505080611e68575090816139d89293611d7481613d65565b906138ba565b6139ee9082849397950390613c98565b50611e68575090826139ff92613cf6565b6139d8565b6064919003600a02049094019338806139ad565b90919892509751613a2a575b50613990565b955038613a24565b905038613920565b8181803e516137d1565b613b97945082935090613a8c917e42dc53000000000000000000000000000000000000000000000000000000006020613b6b9501526102006024860152610224850191612709565b613b3a604484018860806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152846123c6565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018952886121ed565b60008761379d565b5081356135e2565b73ffffffffffffffffffffffffffffffffffffffff168015613c3a57600080809381935af1613bd4612450565b5015613bdc57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff166000526000602052613cc66040600020918254612409565b80915590565b610120610100820151910151808214613cf257480180821015613ced575090565b905090565b5090565b9190917f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f6080602083015192519473ffffffffffffffffffffffffffffffffffffffff946020868851169660e089015116970151916040519283526000602084015260408301526060820152a4565b60208101519051907f67b4fa9642f42120bf031f3051d1824b0fe25627945b27b8a6a65d5761d5482e60208073ffffffffffffffffffffffffffffffffffffffff855116940151604051908152a3565b613dcd604092959493956060835260608301906128ec565b9460208201520152565b8015613e6457600060408051613dec816121d1565b828152826020820152015273ffffffffffffffffffffffffffffffffffffffff811690604065ffffffffffff91828160a01c16908115613e5c575b60d01c92825191613e37836121d1565b8583528460208401521691829101524211908115613e5457509091565b905042109091565b839150613e27565b5060009060009056fea2646970667358221220b094fd69f04977ae9458e5ba422d01cd2d20dbcfca0992ff37f19aa07deec25464736f6c6343000817003360808060405234610016576101c3908161001c8239f35b600080fdfe6080600436101561000f57600080fd5b6000803560e01c63570e1a361461002557600080fd5b3461018a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261018a576004359167ffffffffffffffff9081841161018657366023850112156101865783600401358281116101825736602482870101116101825780601411610182577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec810192808411610155577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8501160116830190838210908211176101555792846024819482600c60209a968b9960405286845289840196603889018837830101525193013560601c5af1908051911561014d575b5073ffffffffffffffffffffffffffffffffffffffff60405191168152f35b90503861012e565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b8380fd5b8280fd5b80fdfea26469706673582212207adef8895ad3393b02fab10a111d85ea80ff35366aa43995f4ea20e67f29200664736f6c63430008170033
Deployed Bytecode
0x60806040526004361015610024575b361561001957600080fd5b61002233612748565b005b60003560e01c806242dc5314611b0057806301ffc9a7146119ae5780630396cb60146116765780630bd28e3b146115fa5780631b2e01b814611566578063205c2878146113d157806322cdde4c1461136b57806335567e1a146112b35780635287ce12146111a557806370a0823114611140578063765e827f14610e82578063850aaf6214610dc35780639b249f6914610c74578063b760faf914610c3a578063bb9fe6bf14610a68578063c23a5cea146107c4578063dbed18e0146101a15763fc7e286d0361000e573461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61013a61229f565b16600052600060205260a0604060002065ffffffffffff6001825492015460405192835260ff8116151560208401526dffffffffffffffffffffffffffff8160081c16604084015263ffffffff8160781c16606084015260981c166080820152f35b600080fd5b3461019c576101af36612317565b906101b86129bd565b60009160005b82811061056f57506101d08493612588565b6000805b8481106102fc5750507fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000809360005b81811061024757610240868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2613ba7565b6001600255005b6102a261025582848a612796565b73ffffffffffffffffffffffffffffffffffffffff6102766020830161282a565b167f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a2806127d6565b906000915b8083106102b957505050600101610209565b909194976102f36102ed6001926102e78c8b6102e0826102da8e8b8d61269d565b9261265a565b5191613597565b90612409565b99612416565b950191906102a7565b6020610309828789612796565b61031f61031682806127d6565b9390920161282a565b9160009273ffffffffffffffffffffffffffffffffffffffff8091165b8285106103505750505050506001016101d4565b909192939561037f83610378610366848c61265a565b516103728b898b61269d565b856129f6565b9290613dd7565b9116840361050a576104a5576103958491613dd7565b9116610440576103b5576103aa600191612416565b96019392919061033c565b60a487604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608489604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b61057a818487612796565b9361058585806127d6565b919095602073ffffffffffffffffffffffffffffffffffffffff6105aa82840161282a565b1697600192838a1461076657896105da575b5050505060019293949550906105d191612409565b939291016101be565b8060406105e892019061284b565b918a3b1561019c57929391906040519485937f2dd8113300000000000000000000000000000000000000000000000000000000855288604486016040600488015252606490818601918a60051b8701019680936000915b8c83106106e657505050505050838392610684927ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8560009803016024860152612709565b03818a5afa90816106d7575b506106c657602486604051907f86a9f7500000000000000000000000000000000000000000000000000000000082526004820152fd5b93945084936105d1600189806105bc565b6106e0906121bd565b88610690565b91939596977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c908a9294969a0301865288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181121561019c57836107538793858394016128ec565b9a0196019301909189979695949261063f565b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b3461019c576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576107fc61229f565b33600052600082526001604060002001908154916dffffffffffffffffffffffffffff8360081c16928315610a0a5765ffffffffffff8160981c1680156109ac57421061094e5760009373ffffffffffffffffffffffffffffffffffffffff859485947fffffffffffffff000000000000000000000000000000000000000000000000ff86951690556040517fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda33391806108da8786836020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b0390a2165af16108e8612450565b50156108f057005b606490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b3461019c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c573360005260006020526001604060002001805463ffffffff8160781c16908115610bdc5760ff1615610b7e5765ffffffffffff908142160191818311610b4f5780547fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff001678ffffffffffff00000000000000000000000000000000000000609885901b161790556040519116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a2005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610022610c6f61229f565b612748565b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043567ffffffffffffffff811161019c576020610cc8610d1b9236906004016122c2565b919073ffffffffffffffffffffffffffffffffffffffff9260405194859283927f570e1a360000000000000000000000000000000000000000000000000000000084528560048501526024840191612709565b03816000857f000000000000000000000000efc2c1444ebcc4db75e7613d20c6a62ff67a167c165af1908115610db757602492600092610d86575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b610da991925060203d602011610db0575b610da181836121ed565b8101906126dd565b9083610d56565b503d610d97565b6040513d6000823e3d90fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610dfa61229f565b60243567ffffffffffffffff811161019c57600091610e1e839236906004016122c2565b90816040519283928337810184815203915af4610e39612450565b90610e7e6040519283927f99410554000000000000000000000000000000000000000000000000000000008452151560048401526040602484015260448301906123c6565b0390fd5b3461019c57610e9036612317565b610e9b9291926129bd565b610ea483612588565b60005b848110610f1c57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000915b858310610eec576102408585613ba7565b909193600190610f12610f0087898761269d565b610f0a888661265a565b519088613597565b0194019190610edb565b610f47610f40610f2e8385979561265a565b51610f3a84898761269d565b846129f6565b9190613dd7565b73ffffffffffffffffffffffffffffffffffffffff929183166110db5761107657610f7190613dd7565b911661101157610f8657600101929092610ea7565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608483604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61118c61229f565b1660005260006020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff6111f161229f565b6000608060405161120181612155565b828152826020820152826040820152826060820152015216600052600060205260a06040600020608060405161123681612155565b6001835493848352015490602081019060ff8316151582526dffffffffffffffffffffffffffff60408201818560081c16815263ffffffff936060840193858760781c16855265ffffffffffff978891019660981c1686526040519788525115156020880152511660408601525116606084015251166080820152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760206112ec61229f565b73ffffffffffffffffffffffffffffffffffffffff6113096122f0565b911660005260018252604060002077ffffffffffffffffffffffffffffffffffffffffffffffff821660005282526040600020547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b3461019c577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60208136011261019c576004359067ffffffffffffffff821161019c5761012090823603011261019c576113c9602091600401612480565b604051908152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761140861229f565b60243590336000526000602052604060002090815491828411611508576000808573ffffffffffffffffffffffffffffffffffffffff8295839561144c848a612443565b90556040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af16114a2612450565b50156114aa57005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761159d61229f565b73ffffffffffffffffffffffffffffffffffffffff6115ba6122f0565b9116600052600160205277ffffffffffffffffffffffffffffffffffffffffffffffff604060002091166000526020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043577ffffffffffffffffffffffffffffffffffffffffffffffff811680910361019c5733600052600160205260406000209060005260205260406000206116728154612416565b9055005b6020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043563ffffffff9182821680920361019c5733600052600081526040600020928215611950576001840154908160781c1683106118f2576116f86dffffffffffffffffffffffffffff9182349160081c16612409565b93841561189457818511611836579065ffffffffffff61180592546040519061172082612155565b8152848101926001845260408201908816815260608201878152600160808401936000855233600052600089526040600020905181550194511515917fffffffffffffffffffffffffff0000000000000000000000000000000000000060ff72ffffffff0000000000000000000000000000006effffffffffffffffffffffffffff008954945160081b16945160781b1694169116171717835551167fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffff78ffffffffffff0000000000000000000000000000000000000083549260981b169116179055565b6040519283528201527fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c0160403392a2005b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361019c57807f60fc6b6e0000000000000000000000000000000000000000000000000000000060209214908115611ad6575b8115611aac575b8115611a82575b8115611a58575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482611a4d565b7f3e84f0210000000000000000000000000000000000000000000000000000000081149150611a46565b7fcf28ef970000000000000000000000000000000000000000000000000000000081149150611a3f565b7f915074d80000000000000000000000000000000000000000000000000000000081149150611a38565b3461019c576102007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5767ffffffffffffffff60043581811161019c573660238201121561019c57611b62903690602481600401359101612268565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101c0811261019c5761014060405191611b9e83612155565b1261019c5760405192611bb0846121a0565b60243573ffffffffffffffffffffffffffffffffffffffff8116810361019c578452602093604435858201526064356040820152608435606082015260a435608082015260c43560a082015260e43560c08201526101043573ffffffffffffffffffffffffffffffffffffffff8116810361019c5760e08201526101243561010082015261014435610120820152825261016435848301526101843560408301526101a43560608301526101c43560808301526101e43590811161019c57611c7c9036906004016122c2565b905a3033036120f7578351606081015195603f5a0260061c61271060a0840151890101116120ce5760009681519182611ff0575b5050505090611cca915a9003608085015101923691612268565b925a90600094845193611cdc85613ccc565b9173ffffffffffffffffffffffffffffffffffffffff60e0870151168015600014611ea957505073ffffffffffffffffffffffffffffffffffffffff855116935b5a9003019360a06060820151910151016080860151850390818111611e95575b50508302604085015192818410600014611dce5750506003811015611da157600203611d79576113c99293508093611d7481613d65565b613cf6565b5050507fdeadaa51000000000000000000000000000000000000000000000000000000008152fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b81611dde92979396940390613c98565b506003841015611e6857507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f60808683015192519473ffffffffffffffffffffffffffffffffffffffff865116948873ffffffffffffffffffffffffffffffffffffffff60e0890151169701519160405192835215898301528760408301526060820152a46113c9565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526021600452fd5b6064919003600a0204909301928780611d3d565b8095918051611eba575b5050611d1d565b6003861015611fc1576002860315611eb35760a088015190823b1561019c57600091611f2491836040519586809581947f7c627b210000000000000000000000000000000000000000000000000000000083528d60048401526080602484015260848301906123c6565b8b8b0260448301528b60648301520393f19081611fad575b50611fa65787893d610800808211611f9e575b506040519282828501016040528184528284013e610e7e6040519283927fad7954bc000000000000000000000000000000000000000000000000000000008452600484015260248301906123c6565b905083611f4f565b8980611eb3565b611fb89199506121bd565b6000978a611f3c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91600092918380938c73ffffffffffffffffffffffffffffffffffffffff885116910192f115612023575b808080611cb0565b611cca929195503d6108008082116120c6575b5060405190888183010160405280825260008983013e805161205f575b5050600194909161201b565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20188870151918973ffffffffffffffffffffffffffffffffffffffff8551169401516120bc604051928392835260408d84015260408301906123c6565b0390a38680612053565b905088612036565b877fdeaddead000000000000000000000000000000000000000000000000000000006000526000fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b60a0810190811067ffffffffffffffff82111761217157604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610140810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157604052565b6060810190811067ffffffffffffffff82111761217157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9291926122748261222e565b9161228260405193846121ed565b82948184528183011161019c578281602093846000960137010152565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9181601f8401121561019c5782359167ffffffffffffffff831161019c576020838186019501011161019c57565b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261019c5760043567ffffffffffffffff9283821161019c578060238301121561019c57816004013593841161019c5760248460051b8301011161019c57602401919060243573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b60005b8381106123b65750506000910152565b81810151838201526020016123a6565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093612402815180928187528780880191016123a3565b0116010190565b91908201809211610b4f57565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610b4f5760010190565b91908203918211610b4f57565b3d1561247b573d906124618261222e565b9161246f60405193846121ed565b82523d6000602084013e565b606090565b604061248e8183018361284b565b90818351918237206124a3606084018461284b565b90818451918237209260c06124bb60e083018361284b565b908186519182372091845195602087019473ffffffffffffffffffffffffffffffffffffffff833516865260208301358789015260608801526080870152608081013560a087015260a081013582870152013560e08501526101009081850152835261012083019167ffffffffffffffff918484108385111761217157838252845190206101408501908152306101608601524661018086015260608452936101a00191821183831017612171575251902090565b67ffffffffffffffff81116121715760051b60200190565b9061259282612570565b6040906125a260405191826121ed565b8381527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06125d08295612570565b019160005b8381106125e25750505050565b60209082516125f081612155565b83516125fb816121a0565b600081526000849181838201528187820152816060818184015260809282848201528260a08201528260c08201528260e082015282610100820152826101208201528652818587015281898701528501528301528286010152016125d5565b805182101561266e5760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b919081101561266e5760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18136030182121561019c570190565b9081602091031261019c575173ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b7f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4602073ffffffffffffffffffffffffffffffffffffffff61278a3485613c98565b936040519485521692a2565b919081101561266e5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18136030182121561019c570190565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c57602001918160051b3603831361019c57565b3573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c5760200191813603831361019c57565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561019c57016020813591019167ffffffffffffffff821161019c57813603831361019c57565b61012091813573ffffffffffffffffffffffffffffffffffffffff811680910361019c576129626129476129ba9561299b93855260208601356020860152612937604087018761289c565b9091806040880152860191612709565b612954606086018661289c565b908583036060870152612709565b6080840135608084015260a084013560a084015260c084013560c084015261298d60e085018561289c565b9084830360e0860152612709565b916129ac610100918281019061289c565b929091818503910152612709565b90565b60028054146129cc5760028055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b926000905a93805194843573ffffffffffffffffffffffffffffffffffffffff811680910361019c5786526020850135602087015260808501356fffffffffffffffffffffffffffffffff90818116606089015260801c604088015260a086013560c088015260c086013590811661010088015260801c610120870152612a8060e086018661284b565b801561357b576034811061351d578060141161019c578060241161019c5760341161019c57602481013560801c60a0880152601481013560801c60808801523560601c60e08701525b612ad285612480565b60208301526040860151946effffffffffffffffffffffffffffff8660c08901511760608901511760808901511760a0890151176101008901511761012089015117116134bf57604087015160608801510160808801510160a08801510160c0880151016101008801510296835173ffffffffffffffffffffffffffffffffffffffff81511690612b66604085018561284b565b806131e4575b505060e0015173ffffffffffffffffffffffffffffffffffffffff1690600082156131ac575b6020612bd7918b828a01516000868a604051978896879586937f19822f7c00000000000000000000000000000000000000000000000000000000855260048501613db5565b0393f160009181613178575b50612c8b573d8c610800808311612c83575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141323320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612bf5565b9a92939495969798999a91156130f2575b509773ffffffffffffffffffffffffffffffffffffffff835116602084015190600052600160205260406000208160401c60005260205267ffffffffffffffff604060002091825492612cee84612416565b9055160361308d575a8503116130285773ffffffffffffffffffffffffffffffffffffffff60e0606093015116612d42575b509060a09184959697986040608096015260608601520135905a900301910152565b969550505a9683519773ffffffffffffffffffffffffffffffffffffffff60e08a01511680600052600060205260406000208054848110612fc3576080612dcd9a9b9c600093878094039055015192602089015183604051809d819582947f52b7512c0000000000000000000000000000000000000000000000000000000084528c60048501613db5565b039286f1978860009160009a612f36575b50612e86573d8b610800808311612e7e575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141333320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612df0565b9991929394959697989998925a900311612eab57509096959094939291906080612d20565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602760448201527f41413336206f766572207061796d6173746572566572696669636174696f6e4760648201527f61734c696d6974000000000000000000000000000000000000000000000000006084820152fd5b915098503d90816000823e612f4b82826121ed565b604081838101031261019c5780519067ffffffffffffffff821161019c57828101601f83830101121561019c578181015191612f868361222e565b93612f9460405195866121ed565b838552820160208483850101011161019c57602092612fba9184808701918501016123a3565b01519838612dde565b60848b604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413331207061796d6173746572206465706f73697420746f6f206c6f7700006064820152fd5b608490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413236206f76657220766572696669636174696f6e4761734c696d697400006064820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601a60448201527f4141323520696e76616c6964206163636f756e74206e6f6e63650000000000006064820152fd5b600052600060205260406000208054808c11613113578b9003905538612c9c565b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152fd5b9091506020813d6020116131a4575b81613194602093836121ed565b8101031261019c57519038612be3565b3d9150613187565b508060005260006020526040600020548a81116000146131d75750612bd7602060005b915050612b92565b6020612bd7918c036131cf565b833b61345a57604088510151602060405180927f570e1a360000000000000000000000000000000000000000000000000000000082528260048301528160008161323260248201898b612709565b039273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000efc2c1444ebcc4db75e7613d20c6a62ff67a167c1690f1908115610db75760009161343b575b5073ffffffffffffffffffffffffffffffffffffffff811680156133d6578503613371573b1561330c5760141161019c5773ffffffffffffffffffffffffffffffffffffffff9183887fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d604060e0958787602086015195510151168251913560601c82526020820152a391612b6c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152fd5b60848e604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313420696e6974436f6465206d7573742072657475726e2073656e6465726064820152fd5b60848f604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601b60448201527f4141313320696e6974436f6465206661696c6564206f72204f4f4700000000006064820152fd5b613454915060203d602011610db057610da181836121ed565b3861327c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b5050600060e087015260006080870152600060a0870152612ac9565b9092915a906060810151916040928351967fffffffff00000000000000000000000000000000000000000000000000000000886135d7606084018461284b565b600060038211613b9f575b7f8dd7712f0000000000000000000000000000000000000000000000000000000094168403613a445750505061379d6000926136b292602088015161363a8a5193849360208501528b602485015260648401906128ec565b90604483015203906136727fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0928381018352826121ed565b61379189519485927e42dc5300000000000000000000000000000000000000000000000000000000602085015261020060248501526102248401906123c6565b613760604484018b60806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152876123c6565b039081018352826121ed565b6020918183809351910182305af1600051988652156137bf575b505050505050565b909192939495965060003d8214613a3a575b7fdeaddead00000000000000000000000000000000000000000000000000000000810361385b57608487878051917f220266b600000000000000000000000000000000000000000000000000000000835260048301526024820152600f60448201527f41413935206f7574206f662067617300000000000000000000000000000000006064820152fd5b7fdeadaa510000000000000000000000000000000000000000000000000000000091929395949650146000146138c55750506138a961389e6138b8935a90612443565b608085015190612409565b9083015183611d748295613d65565b905b3880808080806137b7565b909261395290828601518651907ff62676f440ff169a3a9afdbf812e89e7f95975ee8e5c31214ffdef631c5f479273ffffffffffffffffffffffffffffffffffffffff9580878551169401516139483d610800808211613a32575b508a519084818301018c5280825260008583013e8a805194859485528401528a8301906123c6565b0390a35a90612443565b916139636080860193845190612409565b926000905a94829488519761397789613ccc565b948260e08b0151168015600014613a1857505050875116955b5a9003019560a06060820151910151019051860390818111613a04575b5050840290850151928184106000146139de57505080611e68575090816139d89293611d7481613d65565b906138ba565b6139ee9082849397950390613c98565b50611e68575090826139ff92613cf6565b6139d8565b6064919003600a02049094019338806139ad565b90919892509751613a2a575b50613990565b955038613a24565b905038613920565b8181803e516137d1565b613b97945082935090613a8c917e42dc53000000000000000000000000000000000000000000000000000000006020613b6b9501526102006024860152610224850191612709565b613b3a604484018860806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152846123c6565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018952886121ed565b60008761379d565b5081356135e2565b73ffffffffffffffffffffffffffffffffffffffff168015613c3a57600080809381935af1613bd4612450565b5015613bdc57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff166000526000602052613cc66040600020918254612409565b80915590565b610120610100820151910151808214613cf257480180821015613ced575090565b905090565b5090565b9190917f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f6080602083015192519473ffffffffffffffffffffffffffffffffffffffff946020868851169660e089015116970151916040519283526000602084015260408301526060820152a4565b60208101519051907f67b4fa9642f42120bf031f3051d1824b0fe25627945b27b8a6a65d5761d5482e60208073ffffffffffffffffffffffffffffffffffffffff855116940151604051908152a3565b613dcd604092959493956060835260608301906128ec565b9460208201520152565b8015613e6457600060408051613dec816121d1565b828152826020820152015273ffffffffffffffffffffffffffffffffffffffff811690604065ffffffffffff91828160a01c16908115613e5c575b60d01c92825191613e37836121d1565b8583528460208401521691829101524211908115613e5457509091565b905042109091565b839150613e27565b5060009060009056fea2646970667358221220b094fd69f04977ae9458e5ba422d01cd2d20dbcfca0992ff37f19aa07deec25464736f6c63430008170033
Deployed Bytecode Sourcemap
789:28900:3:-:0;;;;;;;;;-1:-1:-1;789:28900:3;;;;;;;;1326:10:7;;;:::i;:::-;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29649:31;789:28900;29649:31;;;789:28900;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;507:47:7;789:28900:3;;507:47:7;;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2322:103:0;;;:::i;:::-;789:28900:3;7689:13;789:28900;7704:11;;;;;;8461:26;;;;;:::i;:::-;789:28900;;8547:11;;;;;;9255:17;;;789:28900;9255:17;;789:28900;;9340:13;789:28900;9355:11;;;;;;9887:9;9813:38;;789:28900;9461:51;9813:38;;;9887:9;:::i;:::-;8024:1;2924:21:0;789:28900:3;;9368:3;9563:11;9423:19;;;;;:::i;:::-;789:28900;9496:14;7892;9496;;;:::i;:::-;789:28900;9461:51;789:28900;9461:51;;9563:11;;:::i;:::-;9635:13;789:28900;9630:159;9650:10;;;;;;9368:3;;;8024:1;789:28900;9340:13;;9662:3;9722:6;;;;9765:9;9685:62;8024:1;9722:6;9698:49;9722:6;;9730:16;9722:6;;;;;;:::i;:::-;9730:16;;:::i;:::-;;9698:49;;:::i;:::-;9685:62;;:::i;:::-;9765:9;;:::i;:::-;9662:3;789:28900;9635:13;;;;8560:3;7892:14;8615:19;;;;;:::i;:::-;8735:14;8685:11;;;;:::i;:::-;8735:14;;;;;:::i;:::-;8810:13;789:28900;;;;;;8825:10;;;;;;8560:3;;;;;8024:1;789:28900;8532:13;;8837:3;8887:16;;;;;20568:34;8887:16;8981:44;8887:16;;;;:::i;:::-;;9010:6;;;;;:::i;:::-;8981:44;;:::i;:::-;20568:34;;;:::i;:::-;789:28900;;20616:32;;20612:111;;20732:96;;21130:43;;;;:::i;:::-;789:28900;;21183:105;;21297:106;;9206:9;8024:1;9206:9;;:::i;:::-;8837:3;789:28900;8810:13;;;;;;21297:106;789:28900;;;;21338:54;;;;789:28900;21338:54;;789:28900;;;;;;;;;;;;;;;;;;;;;21338:54;21183:105;789:28900;;;;21236:41;;;;789:28900;21236:41;;789:28900;;;;;;;;;;;;;;;;21236:41;20732:96;789:28900;;;;20773:44;;;;789:28900;20773:44;;789:28900;;;;;;;;;;;;;;;;20773:44;20612:111;789:28900;;;;20671:41;;;;789:28900;20671:41;;789:28900;;;;;;;;;;;;;;;;20671:41;7717:3;7772:19;;;;;:::i;:::-;7842:11;;;;;:::i;:::-;7892:14;;;;789:28900;7892:14;;;;;:::i;:::-;789:28900;8024:1;;7993:33;;;;789:28900;;8073:33;8069:305;;7717:3;8388:22;;;;8024:1;8388:22;;;;;;;;;:::i;:::-;7717:3;7689:13;;789:28900;7689:13;;8069:305;8226:13;789:28900;8226:13;;;;;:::i;:::-;8191:49;;;;;;789:28900;;;;;;8191:49;;;789:28900;8191:49;;789:28900;;;;;;8191:49;;789:28900;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8191:49;;;;;;;;;789:28900;-1:-1:-1;8187:173:3;;789:28900;;;;8295:46;;;;789:28900;8295:46;;789:28900;8295:46;8187:173;;;-1:-1:-1;8187:173:3;;8388:22;8024:1;8069:305;;;;8191:49;;;;:::i;:::-;;;;789:28900;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3897:10:7;789:28900:3;;;;;3934:10:7;789:28900:3;;;3934:10:7;789:28900:3;;;;;;;;;3962:9:7;;;789:28900:3;;;;;;;4014:21:7;;789:28900:3;;4121:15:7;-1:-1:-1;789:28900:3;;;;;;;;;;;;;;;;;4293:50:7;3897:10;4293:50;;;;;;789:28900:3;;;;;;;;;;;;;;;;;4293:50:7;;;;789:28900:3;4371:38:7;;;;:::i;:::-;;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3248:10:7;789:28900:3;;;;;3277:20:7;789:28900:3;;;3277:20:7;789:28900:3;;;;;;;3277:25:7;;;789:28900:3;;;;;;;;3407:15:7;;;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;3248:10:7;;3532:39;;789:28900:3;;3532:39:7;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;15911:38;;;;;789:28900;15911:38;;;789:28900;15911:38;;789:28900;;;;;;:::i;:::-;15911:38;1099:14;789:28900;1099:14;;789:28900;15911:38;;;;;;;789:28900;15911:38;789:28900;15911:38;;;789:28900;;;;15966:27;;;;789:28900;;15966:27;;789:28900;15966:27;15911:38;;;;;789:28900;15911:38;789:28900;15911:38;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;;789:28900;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;29607:25;;;;;;:::i;:::-;789:28900;;;;29649:31;;;;;;789:28900;;;29649:31;;789:28900;;;;;;;;;;;:::i;:::-;29649:31;;;789:28900;;;;;;;:::i;:::-;2322:103:0;;;;;:::i;:::-;6751:24:3;;;:::i;:::-;789:28900;6830:10;;;;;;7149:21;789:28900;7189:17;;789:28900;7189:17;;789:28900;7221:120;7241:10;;;;;;7380:9;;;;:::i;7253:3::-;7307:6;;;789:28900;7307:6;7289:37;7307:6;;;;;:::i;:::-;7315:10;;;;:::i;:::-;;7289:37;;;:::i;:::-;789:28900;7253:3;789:28900;7226:13;;;;6842:3;20568:34;6973:38;6892:10;;;;;;:::i;:::-;;6996:6;;;;;:::i;:::-;6973:38;;:::i;:::-;20568:34;;;:::i;:::-;789:28900;;;;;20612:111;;20732:96;;21130:43;;;:::i;:::-;789:28900;;21183:105;;21297:106;;789:28900;;6815:13;;;;;21297:106;789:28900;;;;21338:54;;;;789:28900;21338:54;;789:28900;;;;;;;;;;;;;;;;;;;;;21338:54;21183:105;789:28900;;;;21236:41;;;;789:28900;21236:41;;789:28900;;;;;;;;;;;;;;;;21236:41;20732:96;789:28900;;;;20773:44;;;;789:28900;20773:44;;789:28900;;;;;;;;;;;;;;;;20773:44;20612:111;789:28900;;;;20671:41;;;;789:28900;20671:41;;789:28900;;;;;;;;;;;;;;;;20671:41;789:28900;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::i;:::-;;;;;507:19:5;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;507:55:5;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;4805:10:7;;789:28900:3;;;;;;;;;;;4834:30:7;;;;789:28900:3;;;4919:29:7;;789:28900:3;4919:29:7;;;;;;;;:::i;:::-;789:28900:3;;;;;;;;;;;;;;;;4805:10:7;;4963:54;;;789:28900:3;5045:47:7;;;;:::i;:::-;;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::i;:::-;;;;;279:74:5;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;913:10:5;789:28900:3;;893:19:5;789:28900:3;;;;;;;;;;;;;893:38:5;789:28900:3;;893:38:5;:::i;:::-;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;2428:10:7;789:28900:3;;;;;;;;2457:19:7;;;789:28900:3;;2557:20:7;;;789:28900:3;;;;;;2538:39:7;;789:28900:3;;2657:22:7;789:28900:3;2670:9:7;;;789:28900:3;;;;2657:22:7;:::i;:::-;2697:9;;;789:28900:3;;2747:26:7;;;789:28900:3;;;;;;;;;;;;;:::i;:::-;;;2825:137:7;;;789:28900:3;2557:20:7;789:28900:3;;;2825:137:7;;789:28900:3;;;;;2825:137:7;;;789:28900:3;;;2557:20:7;2825:137;;;789:28900:3;;;;2428:10:7;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2977:47:7;789:28900:3;2428:10:7;2977:47;;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1859:126;1887:97;789:28900;1859:126;;:186;;;;;789:28900;1859:236;;;;789:28900;1859:298;;;;789:28900;1859:338;;;;789:28900;;;;;;;;;;1859:338;876:25:1;861:40;;;1859:338:3;;;:298;1953:31;2111:46;;;-1:-1:-1;1859:298:3;;:236;1919:31;2049:46;;;-1:-1:-1;1859:236:3;;:186;1887:29;2001:44;;;-1:-1:-1;1859:186:3;;789:28900;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11186:9;;11235:4;11213:10;:27;789:28900;;11308:14;;789:28900;11356:20;;789:28900;11495:9;11507:2;11495:9;789:28900;;;1296:5;789:28900;11532:31;;789:28900;;;;-1:-1:-1;11491:253:3;;789:28900;1296:5;;;11840:19;;11836:466;;789:28900;12365:9;;;;;1542:4;12365:9;;1542:4;;789:28900;;;;;;;1542:4;;:::i;:::-;12413:48;25391:9;25434:21;789:28900;25499:14;;;25546:26;;;;:::i;:::-;25607:17;789:28900;;25607:17;;1296:5;789:28900;25642:23;;25638:844;789:28900;;;1296:5;;789:28900;1296:5;;789:28900;25638:844;;26517:9;1542:4;;789:28900;26649:20;789:28900;;26649:20;;789:28900;26672:31;;789:28900;;;;;;1542:4;;26913:36;;;;26909:274;;25638:844;789:28900;;;;;;;;27311:23;;;;27307:793;27311:23;;;789:28900;;;;;;;;27366:36;27358:44;27366:36;;27571:9;27426:23;;;;27489:6;;;;:::i;:::-;27571:9;:::i;27354:438::-;27628:146;;;;;;;789:28900;;;;;;;;;;27307:793;1542:4;27888:40;1542:4;;;;;;27888:40;;:::i;:::-;;789:28900;;;;;;;6100:237;789:28900;;;;1542:4;6163:14;;1296:5;789:28900;1296:5;;789:28900;6198:24;;789:28900;;6198:24;;1296:5;789:28900;6236:20;;789:28900;;;;;;;27961:41;789:28900;;;;;;;;;;;;;6100:237;27307:793;;789:28900;;;;;;;;;;26909:274;789:28900;1542:4;;;1595:2;789:28900;;;;;;26909:274;;;;25638:844;25754:25;;;1296:5;;25797:671;;25638:844;;;;;25797:671;789:28900;;;;;;25913:36;25905:44;;25901:549;25797:671;25901:549;789:28900;26015:31;;789:28900;25981:160;;;;;;789:28900;;;;;;;25981:160;;;;;;789:28900;25981:160;;;789:28900;25981:160;;789:28900;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;25981:160;;;;;;;25901:549;-1:-1:-1;25977:451:3;;1204:349:17;;;1542:4:3;1204:349:17;;;;;25977:451:3;1204:349:17;789:28900:3;1204:349:17;;;;;;;789:28900:3;1204:349:17;;;;;;;;789:28900:3;;;26379:22;;;;;;789:28900;26379:22;;789:28900;;;;;;:::i;1204:349:17:-;;;;;;25977:451:3;25901:549;;25797:671;;25981:160;;;;;;:::i;:::-;789:28900;25981:160;;;;789:28900;;;;;;;;;;11836:466;1296:5;789:28900;1296:5;;;;;;789:28900;1296:5;;789:28900;378:118:17;;;;11960:8:3;11956:336;;11836:466;;;;;;11956:336;1542:4;1204:349:17;;;;;1542:4:3;1204:349:17;;;;;11956:336:3;1204:349:17;789:28900:3;1204:349:17;;;;;;;789:28900:3;1204:349:17;;;;789:28900:3;1204:349:17;;;;1296:5:3;;12069:152;;11956:336;12238:39;;789:28900;11956:336;;;;;12069:152;12119:83;789:28900;;;1542:4;1296:5;;789:28900;1296:5;;789:28900;12180:13;;789:28900;1542:4;789:28900;;;;;;;;1542:4;;;;789:28900;1542:4;;;;:::i;:::-;12119:83;;;12069:152;;;;1204:349:17;;;;;;11491:253:3;11604:126;;789:28900;11604:126;789:28900;11604:126;789:28900;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;789:28900:3;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1542:4::-;;;;;;;;-1:-1:-1;;1542:4:3;;;;:::o;:::-;;;;;;;;;;;;;;;789:28900;;;1542:4;;1296:5;;789:28900;;;;;;;;;1542:4;;;:::i;:::-;789:28900;;1542:4;;;:::o;789:28900::-;;;;;;;;;;:::o;:::-;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;789:28900:3;;;;:::o;:::-;;;:::o;12516:180::-;1998:15:8;;;;;;;:::i;:::-;2872:173:4;;;;;;;;2062:15:8;;;;;;:::i;:::-;2872:173:4;;;;;;;;2300:23:8;2230:14;2300:23;;;;;;:::i;:::-;2872:173:4;;;;;;;;789:28900:3;;;2342:180:8;1938:12;2342:180;;823:61;789:28900:3;823:61:8;;789:28900:3;;;1938:12:8;;;789:28900:3;;;;;2062:15:8;789:28900:3;;;2115:23:8;789:28900:3;;;2115:23:8;;;789:28900:3;2177:25:8;789:28900:3;;;2177:25:8;;;789:28900:3;;;;;2230:14:8;789:28900:3;2300:23:8;789:28900:3;;;;;;;;;2342:180:8;;789:28900:3;;;;;;;;;;;;;;;;;;1296:5;;4962:25:8;;12633:55:3;;;789:28900;;;12667:4;789:28900;;;;12674:13;789:28900;;;;2062:15:8;12633:55:3;;;789:28900;;;;;;;;;;;;1296:5;12623:66;;12516:180;:::o;789:28900::-;;;;;;;;;;;:::o;:::-;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;-1:-1:-1;789:28900:3;;;;;;;;;;:::o;:::-;;;;;;;;:::i;:::-;;;;;;:::i;:::-;-1:-1:-1;789:28900:3;;-1:-1:-1;789:28900:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1296:5;;789:28900;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;-1:-1:-1;789:28900:3;;;;;;;;;;;:::o;1935:179:7:-;2077:30;789:28900:3;;2025:37:7;2052:9;2025:37;;:::i;:::-;789:28900:3;;;;;;;2077:30:7;;1935:179::o;789:28900:3:-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;:::o;2431:307:0:-;2558:7;789:28900:3;;2558:18:0;2554:86;;2558:7;789:28900:3;;2431:307:0:o;2554:86::-;2599:30;789:28900:3;;2599:30:0;;;;22607:1943:3;;789:28900;22841:9;;22890:17;;;789:28900;;;;;;;;;;;;;13061:12;;;789:28900;13061:12;13045:13;;789:28900;13167:23;;;789:28900;;;;;;13114:20;;;789:28900;13167:23;789:28900;13084:28;;;789:28900;13230:25;;;789:28900;13201:26;;;789:28900;13201:26;13349:14;;789:28900;;;;13296:20;;;789:28900;13167:23;789:28900;13266:28;;;789:28900;13408:23;;;;;;:::i;:::-;13445:27;;;;490:2:8;13496:65:3;;490:2:8;;372;;;;;;434;372;;;490;372;;;434;372;;434;13167:23:3;789:28900;13230:25;13668:31;;789:28900;372:2:8;;;434;13167:23:3;789:28900;13167:23;13629:37;;789:28900;372:2:8;13114:20:3;372:2:8;13408:23:3;13610:17;;789:28900;13441:516;22986:21;;;:::i;:::-;13061:12;22963:20;;789:28900;13084:28;;;789:28900;13201:26;789:28900;13201:26;;;;789:28900;23263:49;13114:20;;;789:28900;23263:72;13167:23;23350:37;;789:28900;23263:124;13230:25;23390:31;;789:28900;23263:158;13296:20;;;789:28900;23263:181;13266:28;;;789:28900;23263:224;23505:33;789:28900;;13084:28;;;789:28900;13114:20;;;789:28900;;13167:23;23350:37;;789:28900;;13230:25;23390:31;;789:28900;;13201:26;;;789:28900;;13296:20;;;789:28900;;23659:93;16744:14;;789:28900;1296:5;;789:28900;16856:11;;13084:28;16856:11;;;;:::i;:::-;14898:20;14894:888;;13441:516;-1:-1:-1;;13408:23:3;16902:17;1296:5;789:28900;;;;16982:23;;16978:182;;13441:516;13061:12;17177:102;22963:20;;;;;1542:4;789:28900;;;13084:28;789:28900;17177:102;;;;;;;789:28900;17177:102;;;;;;:::i;:::-;;;;789:28900;;17177:102;;;13441:516;-1:-1:-1;17173:352:3;;1204:349:17;;1542:4:3;1204:349:17;;;;;17173:352:3;1204:349:17;13084:28:3;1204:349:17;;13061:12:3;1204:349:17;;;;13084:28:3;1204:349:17;;;;789:28900:3;13061:12;1204:349:17;;;789:28900:3;13084:28;789:28900;17423:87;;;;;;17177:102;17423:87;;789:28900;13114:20;789:28900;;;;;;;;;;;;;;13230:25;789:28900;;;;;;;;;:::i;1204:349:17:-;;-1:-1:-1;1204:349:17;;;17173:352:3;17344:32;;;;;;;;;;17173:352;16982:23;17538:369;;17173:352;23642:110;1296:5;789:28900;1296:5;;789:28900;13061:12;13045:13;;789:28900;;;;;13061:12;789:28900;13084:28;789:28900;;;13084:28;789:28900;;;13061:12;789:28900;;13084:28;789:28900;;;;;1373:34:5;;;;:::i;:::-;789:28900:3;;;1373:41:5;23763:140:3;;23950:9;1542:4;;23941:41;23937:138;;789:28900;13408:23;13114:20;24129:17;;1296:5;789:28900;24125:188;;17173:352;24346:17;;13230:25;24346:17;;;;;;13084:28;13167:23;24346:17;;789:28900;13114:20;24395:23;;789:28900;13230:25;789:28900;24496:9;;1542:4;;789:28900;24466:18;;789:28900;22607:1943::o;24125:188::-;24229:73;;;;18780:9;18833:14;;;18881:17;789:28900;13408:23;18881:17;;1296:5;789:28900;;;;;13061:12;789:28900;13084:28;789:28900;;;;19038:25;;;19034:122;;13167:23;19320:144;1542:4;;;789:28900;1542:4;;;;;789:28900;;19265:37;789:28900;22963:20;13061:12;22963:20;;1542:4;789:28900;13084:28;789:28900;19320:144;;;;;;789:28900;19320:144;;;17177:102;19320:144;;;:::i;:::-;;;;;;;789:28900;;;19320:144;;;24125:188;-1:-1:-1;19316:441:3;;1204:349:17;;1542:4:3;1204:349:17;;;;;19316:441:3;1204:349:17;13084:28:3;1204:349:17;;13061:12:3;1204:349:17;;;;13084:28:3;1204:349:17;;;;789:28900:3;13061:12;1204:349:17;;;789:28900:3;13084:28;789:28900;19655:87;;;;;;17177:102;19655:87;;789:28900;13114:20;789:28900;;;;;;;;;;;;;;13230:25;789:28900;;;;;;;;;:::i;1204:349:17:-;;-1:-1:-1;1204:349:17;;;19316:441:3;19540:18;;;;;;;;;;19576:32;19316:441;19783:9;1542:4;;19774:43;19770:149;;-1:-1:-1;24176:126:3;;24125:188;24176:126;;24125:188;;24176:126;;13167:23;24125:188;;19770:149;789:28900;;13084:28;789:28900;19844:60;;;;17177:102;19844:60;;789:28900;13084:28;789:28900;;;;;;;;;;;;;;;;;;;19844:60;19320:144;;;;;;;;789:28900;19320:144;;;;;;:::i;:::-;13084:28;19320:144;;;;789:28900;;;;;;;;;;;;19320:144;;;789:28900;;;;;;;;;;;;;;;;;:::i;:::-;;;13084:28;789:28900;;;;:::i;:::-;;;;19320:144;;13061:12;789:28900;;;;;;;;;13061:12;789:28900;;;;;;;;;;;;:::i;:::-;;;19320:144;;;;19034:122;789:28900;;13084:28;789:28900;19090:51;;;;17177:102;19090:51;;789:28900;13084:28;789:28900;;;;;;;;;;;;;;19090:51;23937:138;789:28900;;13084:28;789:28900;24009:51;;;;17177:102;24009:51;;789:28900;13084:28;789:28900;;;;;;;;;;;;;;24009:51;23763:140;789:28900;;13084:28;789:28900;23845:47;;;;17177:102;23845:47;;789:28900;13084:28;789:28900;;;;;;;;;;;;;;23845:47;17538:369;789:28900;;;13061:12;789:28900;13084:28;789:28900;;;;17710:25;;;17706:123;;1542:4;;;789:28900;;17538:369;;;17706:123;789:28900;;13084:28;789:28900;17766:44;;;;17177:102;17766:44;;789:28900;13084:28;789:28900;;;;;;;;;;;;;;17766:44;17177:102;;;;13061:12;17177:102;;13061:12;17177:102;;;;;;13061:12;17177:102;;;:::i;:::-;;;789:28900;;;;;17177:102;;;;;;;-1:-1:-1;17177:102:3;;16978:182;789:28900;;;;;13061:12;789:28900;13084:28;789:28900;;;17096:21;;;:49;:21;;;:49;17177:102;13061:12;789:28900;17096:49;16978:182;;;;;17096:49;13061:12;17177:102;1542:4;;;17096:49;;14894:888;14990:18;;14986:121;;13084:28;15172:14;;:35;789:28900;13061:12;13084:28;789:28900;15138:80;;789:28900;15138:80;;;;;;789:28900;;;;;;;;;;;:::i;:::-;15138:80;1099:14;789:28900;1099:14;789:28900;15138:80;;;;;;;789:28900;15138:80;;;14894:888;789:28900;;;;15236:21;;15232:115;;15364:17;;15360:116;;15493:19;:24;15489:123;;15670:2;372::8;;;789:28900:3;22963:20;;;15694:77;13084:28;13408:23;22963:20;;;13061:12;22963:20;;1542:4;15746:14;;:24;1296:5;789:28900;;;372:2:8;;13114:20:3;372:2:8;789:28900:3;;13061:12;789:28900;;;15694:77;14894:888;;;15489:123;789:28900;;13084:28;789:28900;15544:53;;;;15138:80;15544:53;;789:28900;13084:28;789:28900;;;;13061:12;789:28900;;;;;;;;;15544:53;15360:116;789:28900;;13084:28;789:28900;15408:53;;;;15138:80;15408:53;;789:28900;13084:28;789:28900;;;;13061:12;789:28900;;;;;;;;;15408:53;15232:115;789:28900;;13084:28;789:28900;15284:48;;;;15138:80;15284:48;;789:28900;13084:28;789:28900;;;;;;;;;;;;;;15284:48;15138:80;;;;13061:12;15138:80;13061:12;15138:80;;;;;;;:::i;:::-;;;;14986:121;789:28900;;13084:28;789:28900;15040:52;;;;;;;789:28900;13084:28;789:28900;;;;;;;;;;;;;;15040:52;789:28900;;13084:28;789:28900;;;;13061:12;789:28900;;;;;;;;;;;;;;;490:2:8;;13084:28:3;789:28900;490:2:8;;;13061:12:3;490:2:8;;;;;;;;789:28900:3;490:2:8;789:28900:3;;;490:2:8;;13441:516:3;13812:17;;789:28900;13408:23;13812:17;;789:28900;;13167:23;13856:37;;789:28900;;13230:25;13911:31;;789:28900;13441:516;;3018:2910;;;;3206:9;3273:20;;;;789:28900;3373:83;;;;;3495:15;789:28900;3495:15;;3273:20;3495:15;;;;:::i;:::-;789:28900;3590:144;;;;;3018:2910;3764:38;;789:28900;3751:51;;3764:38;;3906:17;;;3955:68;789:28900;3906:17;789:28900;3906:17;;;;1542:4;789:28900;;;3851:74;;;3906:17;3851:74;;;;;;;789:28900;;;;;;:::i;:::-;;;;;;3851:74;;;;;;;;;;;;:::i;:::-;789:28900;;;3955:68;;;789:28900;3906:17;3955:68;;;789:28900;3851:74;3955:68;;789:28900;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3955:68;;;;;;;;:::i;:::-;4165:220;;;;;;;;;;;;;789:28900;4165:220;;;;4408:8;4404:1518;;3747:405;3018:2910;;;;;;:::o;4404:1518::-;4432:23;;;;;;;;789:28900;4469:228;;;;;4404:1518;789:28900;4714:35;;789:28900;;1473:13;789:28900;;;;4949:36;;;;;;;789:28900;1473:13;;;;;;;;789:28900;1473:13;789:28900;;;1473:13;4949:36;4710:1202;1402:13;5010:43;;;;;;;;5006:906;1402:13;;;5195:9;;5186:36;:18;5392:9;5195;;5186:18;;:::i;:::-;5207:15;;;789:28900;5186:36;;:::i;:::-;5264:14;;;789:28900;5314:6;;;;;:::i;5392:9::-;5006:906;;4404:1518;;;;;;;;5006:906;5529:17;;5751:18;5529:17;;;;1542:4;5568:14;;789:28900;5489:223;789:28900;1296:5;;;;;789:28900;5611:20;;789:28900;1542:4;1204:349:17;1542:4:3;1204:349:17;;;;;5006:906:3;1204:349:17;;;;;;;;;;;;;;789:28900:3;1204:349:17;;;;789:28900:3;;;;;;;;1542:4;;;;;;;;:::i;:::-;5489:223;;;5760:9;5751:18;;:::i;:::-;5772:15;5751:36;5772:15;;;789:28900;;;5751:36;;:::i;:::-;5817:80;789:28900;25391:9;;25434:21;;25499:14;;;25546:26;;;;:::i;:::-;25607:17;;;;;1296:5;789:28900;25642:23;;25638:844;789:28900;;;1296:5;;;;;789:28900;25638:844;;26517:9;1542:4;;789:28900;26649:20;26672:31;3273:20;26649;;789:28900;26672:31;;789:28900;;;;1542:4;;26913:36;;;;26909:274;;25638:844;789:28900;;;;27279:14;;;789:28900;27311:23;;;;27307:793;27311:23;;;789:28900;;;;;27426:23;;;27571:9;27426:23;27489:6;;;;:::i;27571:9::-;5006:906;;;27307:793;27888:40;1542:4;;;;;;;27888:40;;:::i;:::-;;789:28900;;28075:9;;;;;;:::i;:::-;27307:793;;26909:274;27110:3;1542:4;;;1595:2;789:28900;;;;;;26909:274;;;;25638:844;25754:25;;;;;1296:5;;25797:671;;25638:844;;;;25797:671;789:28900;-1:-1:-1;25797:671:3;;;1204:349:17;;;;;;4469:228:3;;;;;;;;3747:405;4074:63;;;;;;;789:28900;4074:63;789:28900;4074:63;789:28900;4074:63;;;789:28900;4074:63;;;789:28900;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4074:63;;;;;;;;:::i;:::-;789:28900;4062:75;3747:405;;3590:144;;;;;;2433:278;789:28900;;2526:25;;789:28900;;2549:1;2608:35;;;;;;;;;:::i;:::-;;789:28900;;;2433:278::o;789:28900::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1559:259:7;789:28900:3;;1683:8:7;789:28900:3;1683:8:7;789:28900:3;;1730:21:7;789:28900:3;1683:8:7;789:28900:3;;;;1730:21:7;:::i;:::-;789:28900:3;;;1559:259:7;:::o;28360:517:3:-;28570:28;28505:20;;;789:28900;28570:28;;789:28900;28616:36;;;28612:173;;28846:13;789:28900;3216:5:4;;;;;;:13;28360:517:3;:::o;3216:13:4:-;;;28360:517:3;:::o;28612:173::-;28751:19;;:::o;5934:410::-;;;;6100:237;789:28900;6132:17;;;1542:4;6163:14;;789:28900;;1296:5;6132:17;1296:5;;;789:28900;6198:24;;;;1296:5;789:28900;6236:20;;789:28900;;;;;;;-1:-1:-1;6132:17:3;789:28900;;;;;;;;;;;6100:237;5934:410::o;6350:182::-;6462:17;;;1542:4;6481:14;;1296:5;6435:90;6462:17;1296:5;789:28900;1296:5;;789:28900;6504:20;;789:28900;;;;;;6435:90;6350:182::o;789:28900::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::o;21739:500::-;21897:19;;21893:76;;21915:1;789:28900;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;1569:3:4;789:28900:3;;1583:15:4;;;1579:67;;21739:500:3;1697:8:4;789:28900:3;;;;;;;;:::i;:::-;;;;1720:50:4;789:28900:3;1720:50:4;;789:28900:3;;1720:50:4;;;;789:28900:3;22124:15;:33;:70;;;;;22107:87;22204:28;21739:500;:::o;22124:70::-;:15;;;22161:33;22204:28;21739:500;:::o;1579:67:4:-;1610:29;;-1:-1:-1;1579:67:4;;21893:76:3;21932:26;21915:1;21932:26;21915:1;21932:26;:::o
Swarm Source
ipfs://7adef8895ad3393b02fab10a111d85ea80ff35366aa43995f4ea20e67f292006
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
BASE | 36.59% | $3,366.46 | 17.4399 | $58,710.56 | |
ETH | 21.70% | $3,366.01 | 10.3446 | $34,819.97 | |
ARB | 17.45% | $3,366.49 | 8.319 | $28,005.82 | |
OP | 8.41% | $3,366.55 | 4.0089 | $13,496.22 | |
POL | 4.01% | $0.494155 | 13,025.5411 | $6,436.64 | |
POL | <0.01% | $0.998915 | 9.42 | $9.41 | |
FRAXTAL | 2.06% | $3,343.72 | 0.9863 | $3,298.02 | |
BSC | 1.87% | $713.13 | 4.2018 | $2,996.45 | |
BSC | <0.01% | $0.00001 | 804,828 | $8.06 | |
ARBNOVA | 1.79% | $3,370.73 | 0.8529 | $2,874.87 | |
WORLD | 1.28% | $3,366.88 | 0.6097 | $2,052.66 | |
LINEA | 1.24% | $3,366.01 | 0.5921 | $1,992.94 | |
OPBNB | 0.99% | $713.27 | 2.2211 | $1,584.29 | |
AVAX | 0.92% | $40.13 | 36.9362 | $1,482.37 | |
SCROLL | Ether (ETH) | 0.47% | $3,366.01 | 0.2256 | $759.42 |
APE | 0.40% | $1.13 | 568.3629 | $645.02 | |
BLAST | 0.39% | $3,369.95 | 0.1877 | $632.37 | |
XAI | 0.25% | $0.218505 | 1,799.4022 | $393.18 | |
GNO | 0.10% | $0.999743 | 166.5855 | $166.54 | |
CELO | 0.05% | $0.659872 | 124.9846 | $82.47 | |
MANTLE | <0.01% | $1.08 | 12.6945 | $13.75 | |
XDC | <0.01% | $0.137224 | 100.181 | $13.75 |
[ 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.