More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 31,373 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Handle Ops | 1102259 | 20 mins ago | IN | 0 ETH | 0.0000016 | ||||
Handle Ops | 1102206 | 1 hr ago | IN | 0 ETH | 0.00000158 | ||||
Handle Ops | 1102081 | 3 hrs ago | IN | 0 ETH | 0.00000157 | ||||
Handle Ops | 1102012 | 4 hrs ago | IN | 0 ETH | 0.0000016 | ||||
Handle Ops | 1101961 | 4 hrs ago | IN | 0 ETH | 0.0000018 | ||||
Handle Ops | 1101937 | 5 hrs ago | IN | 0 ETH | 0.00000097 | ||||
Handle Ops | 1101934 | 5 hrs ago | IN | 0 ETH | 0.00000164 | ||||
Handle Ops | 1101913 | 5 hrs ago | IN | 0 ETH | 0.000002 | ||||
Handle Ops | 1101766 | 8 hrs ago | IN | 0 ETH | 0.0000009 | ||||
Handle Ops | 1101765 | 8 hrs ago | IN | 0 ETH | 0.00000145 | ||||
Handle Ops | 1101310 | 12 hrs ago | IN | 0 ETH | 0.00000138 | ||||
Handle Ops | 1100921 | 17 hrs ago | IN | 0 ETH | 0.00000085 | ||||
Handle Ops | 1100920 | 17 hrs ago | IN | 0 ETH | 0.00000138 | ||||
Handle Ops | 1100802 | 18 hrs ago | IN | 0 ETH | 0.00000085 | ||||
Handle Ops | 1100801 | 18 hrs ago | IN | 0 ETH | 0.00000135 | ||||
Handle Ops | 1100687 | 20 hrs ago | IN | 0 ETH | 0.00000138 | ||||
Handle Ops | 1100648 | 20 hrs ago | IN | 0 ETH | 0.00000548 | ||||
Handle Ops | 1100550 | 21 hrs ago | IN | 0 ETH | 0.00000138 | ||||
Handle Ops | 1100526 | 22 hrs ago | IN | 0 ETH | 0.00000087 | ||||
Handle Ops | 1100525 | 22 hrs ago | IN | 0 ETH | 0.00000335 | ||||
Handle Ops | 1100356 | 24 hrs ago | IN | 0 ETH | 0.00000087 | ||||
Handle Ops | 1100355 | 24 hrs ago | IN | 0 ETH | 0.00000138 | ||||
Handle Ops | 1100068 | 26 hrs ago | IN | 0 ETH | 0.0000014 | ||||
Handle Ops | 1099919 | 27 hrs ago | IN | 0 ETH | 0.0000014 | ||||
Handle Ops | 1099676 | 29 hrs ago | IN | 0 ETH | 0.00000087 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
1102259 | 20 mins ago | 0.00000166 ETH | ||||
1102259 | 20 mins ago | 0.00000166 ETH | ||||
1102206 | 1 hr ago | 0.00000166 ETH | ||||
1102206 | 1 hr ago | 0.00000166 ETH | ||||
1102081 | 3 hrs ago | 0.00000166 ETH | ||||
1102081 | 3 hrs ago | 0.00000166 ETH | ||||
1102012 | 4 hrs ago | 0.00000166 ETH | ||||
1102012 | 4 hrs ago | 0.00000166 ETH | ||||
1101961 | 4 hrs ago | 0.0000019 ETH | ||||
1101961 | 4 hrs ago | 0.00000185 ETH | ||||
1101937 | 5 hrs ago | 0.00000166 ETH | ||||
1101934 | 5 hrs ago | 0.00000166 ETH | ||||
1101934 | 5 hrs ago | 0.00000189 ETH | ||||
1101913 | 5 hrs ago | 0.00000208 ETH | ||||
1101913 | 5 hrs ago | 0.00000247 ETH | ||||
1101766 | 8 hrs ago | 0.00000149 ETH | ||||
1101765 | 8 hrs ago | 0.00000149 ETH | ||||
1101765 | 8 hrs ago | 0.00000163 ETH | ||||
1101310 | 12 hrs ago | 0.00000143 ETH | ||||
1100921 | 17 hrs ago | 0.00000139 ETH | ||||
1100920 | 17 hrs ago | 0.00000139 ETH | ||||
1100920 | 17 hrs ago | 0.00000139 ETH | ||||
1100802 | 18 hrs ago | 0.00000139 ETH | ||||
1100801 | 18 hrs ago | 0.00000139 ETH | ||||
1100801 | 18 hrs ago | 0.00000139 ETH |
Loading...
Loading
Contract Name:
EntryPoint
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
/** ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation. ** Only one instance required on each chain. **/ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; /* solhint-disable avoid-low-level-calls */ /* solhint-disable no-inline-assembly */ import "../interfaces/IAccount.sol"; import "../interfaces/IPaymaster.sol"; import "../interfaces/IEntryPoint.sol"; import "../utils/Exec.sol"; import "./StakeManager.sol"; import "./SenderCreator.sol"; import "./Helpers.sol"; import "./NonceManager.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard { using UserOperationLib for UserOperation; SenderCreator private immutable senderCreator = new SenderCreator(); // internal value used during simulation: need to query aggregator. address private constant SIMULATE_FIND_AGGREGATOR = address(1); // marker for inner call revert on out of gas bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead'; uint256 private constant REVERT_REASON_MAX_LEN = 2048; /** * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value * in case of signature failure, instead of revert. */ uint256 public constant SIG_VALIDATION_FAILED = 1; /** * compensate the caller's beneficiary address with the collected fees of all UserOperations. * @param beneficiary the address to receive the fees * @param amount amount to transfer. */ function _compensate(address payable beneficiary, uint256 amount) internal { require(beneficiary != address(0), "AA90 invalid beneficiary"); (bool success,) = beneficiary.call{value : amount}(""); require(success, "AA91 failed send to beneficiary"); } /** * execute a user op * @param opIndex 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, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) { uint256 preGas = gasleft(); bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset); try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) { collected = _actualGasCost; } catch { bytes32 innerRevertCode; assembly { returndatacopy(0, 0, 32) innerRevertCode := mload(0) } // handleOps was called with gas limit too low. abort entire bundle. if (innerRevertCode == INNER_OUT_OF_GAS) { //report paymaster, since if it is not deliberately caused by the bundler, // it must be a revert caused by paymaster. revert FailedOp(opIndex, "AA95 out of gas"); } uint256 actualGas = preGas - gasleft() + opInfo.preOpGas; collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas); } } /** * 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(UserOperation[] 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); } //unchecked } /** * Execute a batch of UserOperation with Aggregators * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts) * @param beneficiary the address to receive the fees */ function handleAggregatedOps( UserOpsPerAggregator[] calldata opsPerAggregator, address payable beneficiary ) public nonReentrant { uint256 opasLen = opsPerAggregator.length; uint256 totalOps = 0; for (uint256 i = 0; i < opasLen; i++) { UserOpsPerAggregator calldata opa = opsPerAggregator[i]; UserOperation[] 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); emit BeforeExecution(); uint256 opIndex = 0; for (uint256 a = 0; a < opasLen; a++) { UserOpsPerAggregator calldata opa = opsPerAggregator[a]; UserOperation[] calldata ops = opa.userOps; IAggregator aggregator = opa.aggregator; uint256 opslen = ops.length; for (uint256 i = 0; i < opslen; i++) { UserOpInfo memory opInfo = opInfos[opIndex]; (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo); _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator)); opIndex++; } } uint256 collected = 0; opIndex = 0; for (uint256 a = 0; a < opasLen; a++) { UserOpsPerAggregator calldata opa = opsPerAggregator[a]; emit SignatureAggregatorChanged(address(opa.aggregator)); UserOperation[] calldata ops = opa.userOps; uint256 opslen = ops.length; for (uint256 i = 0; i < opslen; i++) { collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]); opIndex++; } } emit SignatureAggregatorChanged(address(0)); _compensate(beneficiary, collected); } /// @inheritdoc IEntryPoint function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override { UserOpInfo memory opInfo; _simulationOnlyValidations(op); (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo); ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData); numberMarker(); uint256 paid = _executeUserOp(0, op, opInfo); numberMarker(); bool targetSuccess; bytes memory targetResult; if (target != address(0)) { (targetSuccess, targetResult) = target.call(targetCallData); } revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult); } // A memory copy of UserOp static fields only. // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster. struct MemoryUserOp { address sender; uint256 nonce; uint256 callGasLimit; uint256 verificationGasLimit; uint256 preVerificationGas; address paymaster; uint256 maxFeePerGas; uint256 maxPriorityFeePerGas; } struct UserOpInfo { MemoryUserOp mUserOp; bytes32 userOpHash; uint256 prefund; uint256 contextOffset; uint256 preOpGas; } /** * inner function to handle a UserOperation. * Must be declared "external" to open a call context, but it can only be called by handleOps. */ function innerHandleOp(bytes 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; uint callGasLimit = mUserOp.callGasLimit; unchecked { // handleOps was called with gas limit too low. abort entire bundle. if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) { assembly { 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; //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp) return _handlePostOp(0, mode, opInfo, context, actualGas); } } /** * generate a request Id - unique identifier for this request. * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid. */ function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) { return keccak256(abi.encode(userOp.hash(), address(this), block.chainid)); } /** * copy general fields from userOp into the memory opInfo structure. */ function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure { mUserOp.sender = userOp.sender; mUserOp.nonce = userOp.nonce; mUserOp.callGasLimit = userOp.callGasLimit; mUserOp.verificationGasLimit = userOp.verificationGasLimit; mUserOp.preVerificationGas = userOp.preVerificationGas; mUserOp.maxFeePerGas = userOp.maxFeePerGas; mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; bytes calldata paymasterAndData = userOp.paymasterAndData; if (paymasterAndData.length > 0) { require(paymasterAndData.length >= 20, "AA93 invalid paymasterAndData"); mUserOp.paymaster = address(bytes20(paymasterAndData[: 20])); } else { mUserOp.paymaster = address(0); } } /** * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp. * @dev this method always revert. Successful result is ValidationResult error. other errors are failures. * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data. * @param userOp the user operation to validate. */ function simulateValidation(UserOperation calldata userOp) external { UserOpInfo memory outOpInfo; _simulationOnlyValidations(userOp); (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo); StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster); StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender); StakeInfo memory factoryInfo; { bytes calldata initCode = userOp.initCode; address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0); factoryInfo = _getStakeInfo(factory); } ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData); address aggregator = data.aggregator; bool sigFailed = aggregator == address(1); ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund, sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset)); if (aggregator != address(0) && aggregator != address(1)) { AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator)); revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo); } revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo); } function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) { unchecked { //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call. // our security model might call postOp eventually twice uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1; uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas; requiredPrefund = requiredGas * mUserOp.maxFeePerGas; } } // create the sender's contract if needed. function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal { if (initCode.length != 0) { address sender = opInfo.mUserOp.sender; if (sender.code.length != 0) revert FailedOp(opIndex, "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); } } /** * Get counterfactual sender address. * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. * this method always revert, and returns the address in SenderAddressResult error * @param initCode the constructor code to be passed into the UserOperation. */ function getSenderAddress(bytes calldata initCode) public { address sender = senderCreator.createSender(initCode); revert SenderAddressResult(sender); } function _simulationOnlyValidations(UserOperation calldata userOp) internal view { // solhint-disable-next-line no-empty-blocks try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {} catch Error(string memory revertReason) { if (bytes(revertReason).length != 0) { revert FailedOp(0, revertReason); } } } /** * Called only during simulation. * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution. */ function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view { if (initCode.length == 0 && sender.code.length == 0) { // it would revert anyway. but give a meaningful message revert("AA20 account not deployed"); } if (paymasterAndData.length >= 20) { address paymaster = address(bytes20(paymasterAndData[0 : 20])); if (paymaster.code.length == 0) { // it would revert anyway. but give a meaningful message revert("AA30 paymaster not deployed"); } } // always revert revert(""); } /** * call account.validateUserOp. * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund. * decrement account's deposit if needed */ function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund) internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) { unchecked { uint256 preGas = gasleft(); MemoryUserOp memory mUserOp = opInfo.mUserOp; address sender = mUserOp.sender; _createSenderIfNeeded(opIndex, opInfo, op.initCode); address paymaster = mUserOp.paymaster; numberMarker(); uint256 missingAccountFunds = 0; if (paymaster == address(0)) { uint256 bal = balanceOf(sender); missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal; } try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds) returns (uint256 _validationData) { validationData = _validationData; } catch Error(string memory revertReason) { revert FailedOp(opIndex, string.concat("AA23 reverted: ", revertReason)); } catch { revert FailedOp(opIndex, "AA23 reverted (or OOG)"); } 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 = uint112(deposit - requiredPrefund); } gasUsedByValidateAccountPrepayment = preGas - gasleft(); } } /** * 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 */ function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment) internal returns (bytes memory context, uint256 validationData) { unchecked { MemoryUserOp memory mUserOp = opInfo.mUserOp; uint256 verificationGasLimit = mUserOp.verificationGasLimit; require(verificationGasLimit > gasUsedByValidateAccountPrepayment, "AA41 too little verificationGas"); uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment; address paymaster = mUserOp.paymaster; DepositInfo storage paymasterInfo = deposits[paymaster]; uint256 deposit = paymasterInfo.deposit; if (deposit < requiredPreFund) { revert FailedOp(opIndex, "AA31 paymaster deposit too low"); } paymasterInfo.deposit = uint112(deposit - requiredPreFund); try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){ context = _context; validationData = _validationData; } catch Error(string memory revertReason) { revert FailedOp(opIndex, string.concat("AA33 reverted: ", revertReason)); } catch { revert FailedOp(opIndex, "AA33 reverted (or OOG)"); } } } /** * revert if either account validationData or paymaster validationData is expired */ 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"); } } 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). * also make sure total validation doesn't exceed verificationGasLimit * this method is called off-chain (simulateValidation()) and on-chain (from handleOps) * @param opIndex the index of this userOp into the "opInfos" array * @param userOp the userOp to validate */ function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo) private 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 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit | userOp.maxFeePerGas | userOp.maxPriorityFeePerGas; require(maxGasValues <= type(uint120).max, "AA94 gas values overflow"); uint256 gasUsedByValidateAccountPrepayment; (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp); (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund); if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) { revert FailedOp(opIndex, "AA25 invalid account nonce"); } //a "marker" where account opcode validation is done and paymaster opcode validation is about to start // (used only by off-chain simulateValidation) numberMarker(); bytes memory context; if (mUserOp.paymaster != address(0)) { (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment); } unchecked { uint256 gasUsed = preGas - gasleft(); if (userOp.verificationGasLimit < gasUsed) { revert FailedOp(opIndex, "AA40 over verificationGasLimit"); } outOpInfo.prefund = requiredPreFund; outOpInfo.contextOffset = getOffsetOfMemoryBytes(context); outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas; } } /** * process post-operation. * called just after the callData is executed. * if a paymaster is defined and its validation returned a non-empty context, its postOp is called. * the excess amount is refunded to the account (or paymaster - if it was used in the request) * @param opIndex index in the batch * @param mode - whether is called from innerHandleOp, or outside (postOpReverted) * @param opInfo userOp fields and info collected during validation * @param context the context returned in validatePaymasterUserOp * @param actualGas the gas used so far by this user operation */ function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) { uint256 preGas = gasleft(); unchecked { address refundAddress; MemoryUserOp memory mUserOp = opInfo.mUserOp; uint256 gasPrice = getUserOpGasPrice(mUserOp); address paymaster = mUserOp.paymaster; if (paymaster == address(0)) { refundAddress = mUserOp.sender; } else { refundAddress = paymaster; if (context.length > 0) { actualGasCost = actualGas * gasPrice; if (mode != IPaymaster.PostOpMode.postOpReverted) { IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost); } else { // solhint-disable-next-line no-empty-blocks try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {} catch Error(string memory reason) { revert FailedOp(opIndex, string.concat("AA50 postOp reverted: ", reason)); } catch { revert FailedOp(opIndex, "AA50 postOp revert"); } } } } actualGas += preGas - gasleft(); actualGasCost = actualGas * gasPrice; if (opInfo.prefund < actualGasCost) { revert FailedOp(opIndex, "AA51 prefund below actualGasCost"); } uint256 refund = opInfo.prefund - actualGasCost; _incrementDeposit(refundAddress, refund); bool success = mode == IPaymaster.PostOpMode.opSucceeded; emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas); } // unchecked } /** * the gas price this UserOp agrees to pay. * relayer/block builder might submit the TX with higher priorityFee, but the user should not */ function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) { unchecked { uint256 maxFeePerGas = mUserOp.maxFeePerGas; uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas; if (maxFeePerGas == maxPriorityFeePerGas) { //legacy mode (for networks that don't support basefee opcode) return maxFeePerGas; } return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee); } } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) { assembly {offset := data} } function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) { assembly {data := offset} } //place the NUMBER opcode in the code. // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the // account and paymaster. function numberMarker() internal view { assembly {mstore(0, number())} } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @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; 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 require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // 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.8.12; /* solhint-disable no-inline-assembly */ /** * returned data from validateUserOp. * validateUserOp returns a uint256, with 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 function _parseValidationData(uint validationData) pure returns (ValidationData memory data) { address aggregator = address(uint160(validationData)); uint48 validUntil = uint48(validationData >> 160); if (validUntil == 0) { validUntil = type(uint48).max; } uint48 validAfter = uint48(validationData >> (48 + 160)); return ValidationData(aggregator, validAfter, validUntil); } // intersect account and paymaster ranges. function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) { ValidationData memory accountValidationData = _parseValidationData(validationData); ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData); address aggregator = accountValidationData.aggregator; if (aggregator == address(0)) { aggregator = pmValidationData.aggregator; } uint48 validAfter = accountValidationData.validAfter; uint48 validUntil = accountValidationData.validUntil; uint48 pmValidAfter = pmValidationData.validAfter; uint48 pmValidUntil = pmValidationData.validUntil; if (validAfter < pmValidAfter) validAfter = pmValidAfter; if (validUntil > pmValidUntil) validUntil = pmValidUntil; return ValidationData(aggregator, validAfter, validUntil); } /** * helper to pack the return value for validateUserOp * @param data - the ValidationData to pack */ function _packValidationData(ValidationData memory data) pure returns (uint256) { return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48)); } /** * helper to pack the return value for validateUserOp, when not using an aggregator * @param sigFailed - true for signature failure, false for success * @param validUntil last timestamp this UserOperation is valid (or zero for infinite) * @param validAfter first timestamp this UserOperation is valid */ function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) { return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48)); } /** * keccak function over calldata. * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it. */ function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) { assembly { let mem := mload(0x40) let len := data.length calldatacopy(mem, data.offset, len) ret := keccak256(mem, len) } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; import "../interfaces/IEntryPoint.sol"; /** * nonce management functionality */ contract NonceManager is INonceManager { /** * The next valid sequence number for a given nonce key. */ mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber; 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() */ 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.12; /** * helper contract for EntryPoint, to call userOp.initCode from a "neutral" address, * which is explicitly not the entryPoint itself. */ contract SenderCreator { /** * call the "initCode" factory to create and return the sender account address * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata * @return sender the returned address of the created account, or zero address on failure. */ function createSender(bytes calldata initCode) external returns (address sender) { address factory = address(bytes20(initCode[0 : 20])); bytes memory initCallData = initCode[20 :]; bool success; /* solhint-disable no-inline-assembly */ assembly { 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-only pragma solidity ^0.8.12; import "../interfaces/IStakeManager.sol"; /* solhint-disable avoid-low-level-calls */ /* solhint-disable not-rely-on-time */ /** * manage deposits and stakes. * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account) * stake is value locked for at least "unstakeDelay" by a paymaster. */ abstract contract StakeManager is IStakeManager { /// maps paymaster to their deposits and stakes mapping(address => DepositInfo) public deposits; /// @inheritdoc IStakeManager function getDepositInfo(address account) public view returns (DepositInfo memory info) { return deposits[account]; } // internal method to return just the stake info function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) { DepositInfo storage depositInfo = deposits[addr]; info.stake = depositInfo.stake; info.unstakeDelaySec = depositInfo.unstakeDelaySec; } /// return the deposit (for gas payment) of the account function balanceOf(address account) public view returns (uint256) { return deposits[account].deposit; } receive() external payable { depositTo(msg.sender); } function _incrementDeposit(address account, uint256 amount) internal { DepositInfo storage info = deposits[account]; uint256 newAmount = info.deposit + amount; require(newAmount <= type(uint112).max, "deposit overflow"); info.deposit = uint112(newAmount); } /** * add to the deposit of the given account */ function depositTo(address account) public payable { _incrementDeposit(account, msg.value); DepositInfo storage info = deposits[account]; emit Deposited(account, info.deposit); } /** * add to the account's stake - amount and delay * any pending unstake is first cancelled. * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn. */ function addStake(uint32 unstakeDelaySec) public payable { DepositInfo storage info = deposits[msg.sender]; require(unstakeDelaySec > 0, "must specify unstake delay"); require(unstakeDelaySec >= info.unstakeDelaySec, "cannot decrease unstake time"); uint256 stake = info.stake + msg.value; require(stake > 0, "no stake specified"); require(stake <= type(uint112).max, "stake overflow"); deposits[msg.sender] = DepositInfo( info.deposit, true, uint112(stake), unstakeDelaySec, 0 ); emit StakeLocked(msg.sender, stake, unstakeDelaySec); } /** * attempt to unlock the stake. * the value can be withdrawn (using withdrawStake) after the unstake delay. */ function unlockStake() external { DepositInfo storage info = deposits[msg.sender]; require(info.unstakeDelaySec != 0, "not staked"); require(info.staked, "already unstaking"); 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 = uint112(info.deposit - withdrawAmount); emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount); (bool success,) = withdrawAddress.call{value : withdrawAmount}(""); require(success, "failed to withdraw"); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; import "./UserOperation.sol"; interface IAccount { /** * Validate user's signature and nonce * the entryPoint will make the call to the recipient only if this validation call returns successfully. * signature failure should be reported by returning SIG_VALIDATION_FAILED (1). * This allows making a "simulation call" without a valid signature * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure. * * @dev Must validate caller is the entryPoint. * Must validate the signature and nonce * @param userOp the operation that is about to be executed. * @param userOpHash hash of the user's request data. can be used as the basis for signature. * @param 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(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds) external returns (uint256 validationData); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; import "./UserOperation.sol"; /** * Aggregated Signatures validator. */ interface IAggregator { /** * validate aggregated signature. * revert if the aggregated signature does not match the given list of operations. */ function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view; /** * validate signature of a single userOp * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps. * @param userOp the userOperation received from the user. * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps. * (usually empty, unless account and aggregator support some kind of "multisig" */ function validateUserOpSignature(UserOperation calldata userOp) external view returns (bytes memory sigForUserOp); /** * aggregate multiple signatures into a single value. * This method is called off-chain to calculate the signature to pass with handleOps() * bundler MAY use optimized custom code perform this aggregation * @param userOps array of UserOperations to collect the signatures from. * @return aggregatedSignature the aggregated signature */ function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature); }
/** ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation. ** Only one instance required on each chain. **/ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; /* solhint-disable avoid-low-level-calls */ /* solhint-disable no-inline-assembly */ /* solhint-disable reason-string */ import "./UserOperation.sol"; import "./IStakeManager.sol"; import "./IAggregator.sol"; import "./INonceManager.sol"; interface IEntryPoint is IStakeManager, INonceManager { /*** * An event emitted after each successful request * @param userOpHash - unique identifier for the request (hash its entire content, except signature). * @param sender - the account that generates this request. * @param paymaster - if non-null, the paymaster that pays for this request. * @param nonce - the nonce value from the request. * @param success - true if the sender transaction succeeded, false if reverted. * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation. * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution). */ event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed); /** * account "sender" was deployed. * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow. * @param sender the account that is deployed * @param factory the factory used to deploy this account (in the initCode) * @param paymaster the paymaster used by this UserOp */ event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster); /** * An event emitted if the UserOperation "callData" reverted with non-zero length * @param userOpHash the request unique identifier. * @param sender the sender of this request * @param nonce the nonce used in the request * @param revertReason - the return bytes from the (reverted) call to "callData". */ event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason); /** * an event emitted by handleOps(), before starting the execution loop. * any event emitted before this event, is part of the validation. */ event BeforeExecution(); /** * signature aggregator used by the following UserOperationEvents within this bundle. */ event SignatureAggregatorChanged(address indexed aggregator); /** * a custom revert error of handleOps, to identify the offending op. * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it. * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero) * @param reason - revert reason * The string starts with a unique code "AAmn", where "m" is "1" for factory, "2" for account and "3" for paymaster issues, * so a failure can be attributed to the correct entity. * Should be caught in off-chain handleOps simulation and not happen on-chain. * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts. */ error FailedOp(uint256 opIndex, string reason); /** * error case when a signature aggregator fails to verify the aggregated signature it had created. */ error SignatureValidationFailed(address aggregator); /** * Successful result from simulateValidation. * @param returnInfo gas and time-range returned values * @param senderInfo stake information about the sender * @param factoryInfo stake information about the factory (if any) * @param paymasterInfo stake information about the paymaster (if any) */ error ValidationResult(ReturnInfo returnInfo, StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo); /** * Successful result from simulateValidation, if the account returns a signature aggregator * @param returnInfo gas and time-range returned values * @param senderInfo stake information about the sender * @param factoryInfo stake information about the factory (if any) * @param paymasterInfo stake information about the paymaster (if any) * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator) * bundler MUST use it to verify the signature, or reject the UserOperation */ error ValidationResultWithAggregation(ReturnInfo returnInfo, StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo, AggregatorStakeInfo aggregatorInfo); /** * return value of getSenderAddress */ error SenderAddressResult(address sender); /** * return value of simulateHandleOp */ error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult); //UserOps handled, per aggregator struct UserOpsPerAggregator { UserOperation[] userOps; // aggregator address IAggregator aggregator; // aggregated signature bytes signature; } /** * Execute a batch of UserOperation. * no signature aggregator is used. * if any account requires an aggregator (that is, it returned an aggregator when * performing simulateValidation), then handleAggregatedOps() must be used instead. * @param ops the operations to execute * @param beneficiary the address to receive the fees */ function handleOps(UserOperation[] calldata ops, address payable beneficiary) external; /** * Execute a batch of UserOperation with Aggregators * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts) * @param beneficiary the address to receive the fees */ function handleAggregatedOps( UserOpsPerAggregator[] calldata opsPerAggregator, address payable beneficiary ) external; /** * generate a request Id - unique identifier for this request. * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid. */ function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32); /** * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp. * @dev this method always revert. Successful result is ValidationResult error. other errors are failures. * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data. * @param userOp the user operation to validate. */ function simulateValidation(UserOperation calldata userOp) external; /** * gas and return values during simulation * @param preOpGas the gas used for validation (including preValidationGas) * @param prefund the required prefund for this operation * @param sigFailed validateUserOp's (or paymaster's) signature check failed * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range) * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range) * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp) */ struct ReturnInfo { uint256 preOpGas; uint256 prefund; bool sigFailed; uint48 validAfter; uint48 validUntil; bytes paymasterContext; } /** * returned aggregated signature info. * the aggregator returned by the account, and its current stake. */ struct AggregatorStakeInfo { address aggregator; StakeInfo stakeInfo; } /** * Get counterfactual sender address. * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. * this method always revert, and returns the address in SenderAddressResult error * @param initCode the constructor code to be passed into the UserOperation. */ function getSenderAddress(bytes memory initCode) external; /** * simulate full execution of a UserOperation (including both validation and target execution) * this method will always revert with "ExecutionResult". * it performs full validation of the UserOperation, but ignores signature error. * an optional target address is called after the userop succeeds, and its value is returned * (before the entire call is reverted) * Note that in order to collect the the success/failure of the target call, it must be executed * with trace enabled to track the emitted events. * @param op the UserOperation to simulate * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult * are set to the return from that call. * @param targetCallData callData to pass to target address */ function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; interface INonceManager { /** * Return the next nonce for this sender. * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) * But UserOp with different keys can come with arbitrary order. * * @param sender the account address * @param key the high 192 bit of the nonce * @return nonce a full nonce to pass for next UserOp with this sender. */ function getNonce(address sender, uint192 key) external view returns (uint256 nonce); /** * Manually increment the nonce of the sender. * This method is exposed just for completeness.. * Account does NOT need to call it, neither during validation, nor elsewhere, * as the EntryPoint will update the nonce regardless. * Possible use-case is call it with various keys to "initialize" their nonces to one, so that future * UserOperations will not pay extra for the first transaction with a given key. */ function incrementNonce(uint192 key) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; import "./UserOperation.sol"; /** * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations. * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction. */ interface IPaymaster { enum PostOpMode { opSucceeded, // user op succeeded opReverted, // user op reverted. still has to pay for gas. postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted. } /** * payment validation: check if paymaster agrees to pay. * Must verify sender is the entryPoint. * Revert to reject this request. * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted) * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns. * @param userOp the user operation * @param userOpHash hash of the user's request data. * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp) * @return context value to send to a postOp * zero length to signify postOp is not required. * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure, * otherwise, an address of an "authorizer" contract. * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite" * <6-byte> validAfter - first timestamp this operation is valid * Note that the validation code cannot use block.timestamp (or block.number) directly. */ function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost) external returns (bytes memory context, uint256 validationData); /** * post-operation handler. * Must verify sender is the entryPoint * @param mode enum with the following options: * opSucceeded - user operation succeeded. * opReverted - user op reverted. still has to pay for gas. * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert. * Now this is the 2nd call, after user's op was deliberately reverted. * @param context - the context value returned by validatePaymasterUserOp * @param actualGasCost - actual gas used so far (without this postOp call). */ function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external; }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.12; /** * manage deposits and stakes. * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account) * stake is value locked for at least "unstakeDelay" by the staked entity. */ interface IStakeManager { event Deposited( address indexed account, uint256 totalDeposit ); event Withdrawn( address indexed account, address withdrawAddress, uint256 amount ); /// Emitted when stake or unstake delay are modified event StakeLocked( address indexed account, uint256 totalStaked, uint256 unstakeDelaySec ); /// Emitted once a stake is scheduled for withdrawal event StakeUnlocked( address indexed account, uint256 withdrawTime ); event StakeWithdrawn( address indexed account, address withdrawAddress, uint256 amount ); /** * @param deposit the entity's deposit * @param staked true if this entity is staked. * @param stake actual amount of ether staked for this entity. * @param unstakeDelaySec minimum delay to withdraw the stake. * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps) * and the rest fit into a 2nd cell. * 112 bit allows for 10^15 eth * 48 bit for full timestamp * 32 bit allows 150 years for unstake delay */ struct DepositInfo { uint112 deposit; bool staked; uint112 stake; uint32 unstakeDelaySec; uint48 withdrawTime; } //API struct used by getStakeInfo and simulateValidation struct StakeInfo { uint256 stake; uint256 unstakeDelaySec; } /// @return info - full deposit information of given account function getDepositInfo(address account) external view returns (DepositInfo memory info); /// @return the deposit (for gas payment) of the account function balanceOf(address account) external view returns (uint256); /** * add to the deposit of the given account */ function depositTo(address account) external payable; /** * add to the account's stake - amount and delay * any pending unstake is first cancelled. * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn. */ function addStake(uint32 _unstakeDelaySec) external payable; /** * attempt to unlock the stake. * the value can be withdrawn (using withdrawStake) after the unstake delay. */ function unlockStake() external; /** * withdraw from the (unlocked) stake. * must first call unlockStake and wait for the unstakeDelay to pass * @param withdrawAddress the address to send withdrawn value. */ function withdrawStake(address payable withdrawAddress) external; /** * withdraw from the deposit. * @param withdrawAddress the address to send withdrawn value. * @param withdrawAmount the amount to withdraw. */ function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; /* solhint-disable no-inline-assembly */ import {calldataKeccak} from "../core/Helpers.sol"; /** * User Operation struct * @param sender the sender account of this request. * @param nonce unique value the sender uses to verify it is not a replay. * @param initCode if set, the account contract will be created by this constructor/ * @param callData the method call to execute on this account. * @param callGasLimit the gas limit passed to the callData method call. * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp. * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead. * @param maxFeePerGas same as EIP-1559 gas parameter. * @param maxPriorityFeePerGas same as EIP-1559 gas parameter. * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender. * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID. */ struct UserOperation { address sender; uint256 nonce; bytes initCode; bytes callData; uint256 callGasLimit; uint256 verificationGasLimit; uint256 preVerificationGas; uint256 maxFeePerGas; uint256 maxPriorityFeePerGas; bytes paymasterAndData; bytes signature; } /** * Utility functions helpful when working with UserOperation structs. */ library UserOperationLib { function getSender(UserOperation calldata userOp) internal pure returns (address) { address data; //read sender from userOp, which is first userOp member (saves 800 gas...) assembly {data := calldataload(userOp)} return address(uint160(data)); } //relayer/block builder might submit the TX with higher priorityFee, but the user should not // pay above what he signed for. function gasPrice(UserOperation calldata userOp) internal view returns (uint256) { unchecked { uint256 maxFeePerGas = userOp.maxFeePerGas; uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; if (maxFeePerGas == maxPriorityFeePerGas) { //legacy mode (for networks that don't support basefee opcode) return maxFeePerGas; } return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee); } } function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) { address sender = getSender(userOp); uint256 nonce = userOp.nonce; bytes32 hashInitCode = calldataKeccak(userOp.initCode); bytes32 hashCallData = calldataKeccak(userOp.callData); uint256 callGasLimit = userOp.callGasLimit; uint256 verificationGasLimit = userOp.verificationGasLimit; uint256 preVerificationGas = userOp.preVerificationGas; uint256 maxFeePerGas = userOp.maxFeePerGas; uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData); return abi.encode( sender, nonce, hashInitCode, hashCallData, callGasLimit, verificationGasLimit, preVerificationGas, maxFeePerGas, maxPriorityFeePerGas, hashPaymasterAndData ); } function hash(UserOperation calldata userOp) internal pure returns (bytes32) { return keccak256(pack(userOp)); } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.7.5 <0.9.0; // 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 { 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 { 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 { 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 { 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 { 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)); } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"preOpGas","type":"uint256"},{"internalType":"uint256","name":"paid","type":"uint256"},{"internalType":"uint48","name":"validAfter","type":"uint48"},{"internalType":"uint48","name":"validUntil","type":"uint48"},{"internalType":"bool","name":"targetSuccess","type":"bool"},{"internalType":"bytes","name":"targetResult","type":"bytes"}],"name":"ExecutionResult","type":"error"},{"inputs":[{"internalType":"uint256","name":"opIndex","type":"uint256"},{"internalType":"string","name":"reason","type":"string"}],"name":"FailedOp","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"SenderAddressResult","type":"error"},{"inputs":[{"internalType":"address","name":"aggregator","type":"address"}],"name":"SignatureValidationFailed","type":"error"},{"inputs":[{"components":[{"internalType":"uint256","name":"preOpGas","type":"uint256"},{"internalType":"uint256","name":"prefund","type":"uint256"},{"internalType":"bool","name":"sigFailed","type":"bool"},{"internalType":"uint48","name":"validAfter","type":"uint48"},{"internalType":"uint48","name":"validUntil","type":"uint48"},{"internalType":"bytes","name":"paymasterContext","type":"bytes"}],"internalType":"struct IEntryPoint.ReturnInfo","name":"returnInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"senderInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"factoryInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"paymasterInfo","type":"tuple"}],"name":"ValidationResult","type":"error"},{"inputs":[{"components":[{"internalType":"uint256","name":"preOpGas","type":"uint256"},{"internalType":"uint256","name":"prefund","type":"uint256"},{"internalType":"bool","name":"sigFailed","type":"bool"},{"internalType":"uint48","name":"validAfter","type":"uint48"},{"internalType":"uint48","name":"validUntil","type":"uint48"},{"internalType":"bytes","name":"paymasterContext","type":"bytes"}],"internalType":"struct IEntryPoint.ReturnInfo","name":"returnInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"senderInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"factoryInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"paymasterInfo","type":"tuple"},{"components":[{"internalType":"address","name":"aggregator","type":"address"},{"components":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstakeDelaySec","type":"uint256"}],"internalType":"struct IStakeManager.StakeInfo","name":"stakeInfo","type":"tuple"}],"internalType":"struct IEntryPoint.AggregatorStakeInfo","name":"aggregatorInfo","type":"tuple"}],"name":"ValidationResultWithAggregation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"factory","type":"address"},{"indexed":false,"internalType":"address","name":"paymaster","type":"address"}],"name":"AccountDeployed","type":"event"},{"anonymous":false,"inputs":[],"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":"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"},{"indexed":false,"internalType":"bytes","name":"revertReason","type":"bytes"}],"name":"UserOperationRevertReason","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"withdrawAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"SIG_VALIDATION_FAILED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"}],"name":"_validateSenderAndPaymaster","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"unstakeDelaySec","type":"uint32"}],"name":"addStake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"depositTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"deposits","outputs":[{"internalType":"uint112","name":"deposit","type":"uint112"},{"internalType":"bool","name":"staked","type":"bool"},{"internalType":"uint112","name":"stake","type":"uint112"},{"internalType":"uint32","name":"unstakeDelaySec","type":"uint32"},{"internalType":"uint48","name":"withdrawTime","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getDepositInfo","outputs":[{"components":[{"internalType":"uint112","name":"deposit","type":"uint112"},{"internalType":"bool","name":"staked","type":"bool"},{"internalType":"uint112","name":"stake","type":"uint112"},{"internalType":"uint32","name":"unstakeDelaySec","type":"uint32"},{"internalType":"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":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"}],"name":"getUserOpHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation[]","name":"userOps","type":"tuple[]"},{"internalType":"contract IAggregator","name":"aggregator","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IEntryPoint.UserOpsPerAggregator[]","name":"opsPerAggregator","type":"tuple[]"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"handleAggregatedOps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation[]","name":"ops","type":"tuple[]"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"handleOps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"address","name":"paymaster","type":"address"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"}],"internalType":"struct EntryPoint.MemoryUserOp","name":"mUserOp","type":"tuple"},{"internalType":"bytes32","name":"userOpHash","type":"bytes32"},{"internalType":"uint256","name":"prefund","type":"uint256"},{"internalType":"uint256","name":"contextOffset","type":"uint256"},{"internalType":"uint256","name":"preOpGas","type":"uint256"}],"internalType":"struct EntryPoint.UserOpInfo","name":"opInfo","type":"tuple"},{"internalType":"bytes","name":"context","type":"bytes"}],"name":"innerHandleOp","outputs":[{"internalType":"uint256","name":"actualGasCost","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint192","name":"","type":"uint192"}],"name":"nonceSequenceNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"op","type":"tuple"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"targetCallData","type":"bytes"}],"name":"simulateHandleOp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation","name":"userOp","type":"tuple"}],"name":"simulateValidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"withdrawAddress","type":"address"}],"name":"withdrawStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"withdrawAddress","type":"address"},{"internalType":"uint256","name":"withdrawAmount","type":"uint256"}],"name":"withdrawTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a0604052604051620000129062000055565b604051809103906000f0801580156200002f573d6000803e3d6000fd5b506001600160a01b03166080523480156200004957600080fd5b50600160025562000063565b610213806200402183390190565b608051613f9b620000866000396000818161129c0152612df20152613f9b6000f3fe6080604052600436106101235760003560e01c80638f41ec5a116100a0578063bb9fe6bf11610064578063bb9fe6bf1461043a578063c23a5cea1461044f578063d6383f941461046f578063ee2194231461048f578063fc7e286d146104af57600080fd5b80638f41ec5a146103b2578063957122ab146103c75780639b249f69146103e7578063a619353114610407578063b760faf91461042757600080fd5b8063205c2878116100e7578063205c2878146101f657806335567e1a146102165780634b1d7cf5146102365780635287ce121461025657806370a082311461037357600080fd5b80630396cb60146101385780630bd28e3b1461014b5780631b2e01b81461016b5780631d732756146101b65780631fad948c146101d657600080fd5b366101335761013133610564565b005b600080fd5b6101316101463660046130c5565b6105cb565b34801561015757600080fd5b50610131610166366004613107565b61085a565b34801561017757600080fd5b506101a3610186366004613142565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b3480156101c257600080fd5b506101a36101d136600461333c565b610891565b3480156101e257600080fd5b506101316101f1366004613445565b610a04565b34801561020257600080fd5b5061013161021136600461349b565b610b80565b34801561022257600080fd5b506101a3610231366004613142565b610cfc565b34801561024257600080fd5b50610131610251366004613445565b610d42565b34801561026257600080fd5b5061031b6102713660046134c7565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506001600160a01b031660009081526020818152604091829020825160a08101845281546001600160701b038082168352600160701b820460ff16151594830194909452600160781b90049092169282019290925260019091015463ffffffff81166060830152640100000000900465ffffffffffff16608082015290565b6040805182516001600160701b03908116825260208085015115159083015283830151169181019190915260608083015163ffffffff169082015260809182015165ffffffffffff169181019190915260a0016101ad565b34801561037f57600080fd5b506101a361038e3660046134c7565b6001600160a01b03166000908152602081905260409020546001600160701b031690565b3480156103be57600080fd5b506101a3600181565b3480156103d357600080fd5b506101316103e23660046134e4565b611185565b3480156103f357600080fd5b50610131610402366004613568565b611282565b34801561041357600080fd5b506101a36104223660046135c2565b61133d565b6101316104353660046134c7565b610564565b34801561044657600080fd5b5061013161137f565b34801561045b57600080fd5b5061013161046a3660046134c7565b6114a8565b34801561047b57600080fd5b5061013161048a3660046135f6565b6116e0565b34801561049b57600080fd5b506101316104aa3660046135c2565b6117db565b3480156104bb57600080fd5b5061051e6104ca3660046134c7565b600060208190529081526040902080546001909101546001600160701b0380831692600160701b810460ff1692600160781b9091049091169063ffffffff811690640100000000900465ffffffffffff1685565b604080516001600160701b0396871681529415156020860152929094169183019190915263ffffffff16606082015265ffffffffffff909116608082015260a0016101ad565b61056e81346119b7565b6001600160a01b03811660008181526020818152604091829020805492516001600160701b03909316835292917f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c491015b60405180910390a25050565b33600090815260208190526040902063ffffffff82166106325760405162461bcd60e51b815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c617900000000000060448201526064015b60405180910390fd5b600181015463ffffffff90811690831610156106905760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152606401610629565b80546000906106b0903490600160781b90046001600160701b031661366d565b9050600081116106f75760405162461bcd60e51b81526020600482015260126024820152711b9bc81cdd185ad9481cdc1958da599a595960721b6044820152606401610629565b6001600160701b0381111561073f5760405162461bcd60e51b815260206004820152600e60248201526d7374616b65206f766572666c6f7760901b6044820152606401610629565b6040805160a08101825283546001600160701b0390811682526001602080840182815286841685870190815263ffffffff808b16606088019081526000608089018181523380835296829052908a902098518954955194518916600160781b02600160781b600160e81b0319951515600160701b026effffffffffffffffffffffffffffff199097169190991617949094179290921695909517865551949092018054925165ffffffffffff166401000000000269ffffffffffffffffffff19909316949093169390931717905590517fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c019061084d908490879091825263ffffffff16602082015260400190565b60405180910390a2505050565b3360009081526001602090815260408083206001600160c01b0385168452909152812080549161088983613680565b919050555050565b6000805a90503330146108e65760405162461bcd60e51b815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152606401610629565b8451604081015160608201518101611388015a10156109105763deaddead60e01b60005260206000fd5b8751600090156109a457600061092d846000015160008c86611a53565b9050806109a2576000610941610800611a6b565b80519091501561099c5784600001516001600160a01b03168a602001517f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a2018760200151846040516109939291906136e9565b60405180910390a35b60019250505b505b600088608001515a86030190506109f66000838b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250611a97915050565b9a9950505050505050505050565b610a0c611d8e565b816000816001600160401b03811115610a2757610a27613177565b604051908082528060200260200182016040528015610a6057816020015b610a4d61303b565b815260200190600190039081610a455790505b50905060005b82811015610ad9576000828281518110610a8257610a82613702565b60200260200101519050600080610abd848a8a87818110610aa557610aa5613702565b9050602002810190610ab79190613718565b85611de5565b91509150610ace8483836000611fd0565b505050600101610a66565b506040516000907fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972908290a160005b83811015610b6357610b5781888884818110610b2657610b26613702565b9050602002810190610b389190613718565b858481518110610b4a57610b4a613702565b602002602001015161216c565b90910190600101610b08565b50610b6e8482612293565b505050610b7b6001600255565b505050565b33600090815260208190526040902080546001600160701b0316821115610be95760405162461bcd60e51b815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152606401610629565b8054610bff9083906001600160701b0316613739565b81546001600160701b0319166001600160701b0391909116178155604080516001600160a01b03851681526020810184905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb910160405180910390a26000836001600160a01b03168360405160006040518083038185875af1925050503d8060008114610cab576040519150601f19603f3d011682016040523d82523d6000602084013e610cb0565b606091505b5050905080610cf65760405162461bcd60e51b81526020600482015260126024820152716661696c656420746f20776974686472617760701b6044820152606401610629565b50505050565b6001600160a01b03821660009081526001602090815260408083206001600160c01b038516845290915290819020549082901b67ffffffffffffffff1916175b92915050565b610d4a611d8e565b816000805b82811015610ebe5736868683818110610d6a57610d6a613702565b9050602002810190610d7c919061374c565b9050366000610d8b8380613762565b90925090506000610da260408501602086016134c7565b90506000196001600160a01b03821601610dfe5760405162461bcd60e51b815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152606401610629565b6001600160a01b03811615610e9b576001600160a01b03811663e3563a4f8484610e2b60408901896137ab565b6040518563ffffffff1660e01b8152600401610e4a9493929190613956565b60006040518083038186803b158015610e6257600080fd5b505afa925050508015610e73575060015b610e9b5760405163086a9f7560e41b81526001600160a01b0382166004820152602401610629565b610ea5828761366d565b9550505050508080610eb690613680565b915050610d4f565b506000816001600160401b03811115610ed957610ed9613177565b604051908082528060200260200182016040528015610f1257816020015b610eff61303b565b815260200190600190039081610ef75790505b506040519091507fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f97290600090a16000805b848110156110275736888883818110610f5e57610f5e613702565b9050602002810190610f70919061374c565b9050366000610f7f8380613762565b90925090506000610f9660408501602086016134c7565b90508160005b8181101561100e576000898981518110610fb857610fb8613702565b60200260200101519050600080610fdb8b898987818110610aa557610aa5613702565b91509150610feb84838389611fd0565b8a610ff581613680565b9b5050505050808061100690613680565b915050610f9c565b505050505050808061101f90613680565b915050610f43565b50600080915060005b85811015611140573689898381811061104b5761104b613702565b905060200281019061105d919061374c565b905061106f60408201602083016134c7565b6001600160a01b03167f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d60405160405180910390a23660006110b18380613762565b90925090508060005b81811015611128576110fc888585848181106110d8576110d8613702565b90506020028101906110ea9190613718565b8b8b81518110610b4a57610b4a613702565b611106908861366d565b96508761111281613680565b985050808061112090613680565b9150506110ba565b5050505050808061113890613680565b915050611030565b506040516000907f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d908290a26111768682612293565b5050505050610b7b6001600255565b8315801561119b57506001600160a01b0383163b155b156111e85760405162461bcd60e51b815260206004820152601960248201527f41413230206163636f756e74206e6f74206465706c6f796564000000000000006044820152606401610629565b601481106112605760006111ff60148284866139d3565b611208916139fd565b60601c9050803b60000361125e5760405162461bcd60e51b815260206004820152601b60248201527f41413330207061796d6173746572206e6f74206465706c6f79656400000000006044820152606401610629565b505b60405162461bcd60e51b81526020600482015260006024820152604401610629565b604051632b870d1b60e11b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063570e1a36906112d39086908690600401613a32565b6020604051808303816000875af11580156112f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113169190613a46565b604051633653dc0360e11b81526001600160a01b0382166004820152909150602401610629565b60006113488261238c565b6040805160208101929092523090820152466060820152608001604051602081830303815290604052805190602001209050919050565b3360009081526020819052604081206001810154909163ffffffff90911690036113d85760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081cdd185ad95960b21b6044820152606401610629565b8054600160701b900460ff166114245760405162461bcd60e51b8152602060048201526011602482015270616c726561647920756e7374616b696e6760781b6044820152606401610629565b600181015460009061143c9063ffffffff1642613a63565b60018301805469ffffffffffff00000000191664010000000065ffffffffffff841690810291909117909155835460ff60701b1916845560405190815290915033907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a906020016105bf565b3360009081526020819052604090208054600160781b90046001600160701b03168061150d5760405162461bcd60e51b81526020600482015260146024820152734e6f207374616b6520746f20776974686472617760601b6044820152606401610629565b6001820154640100000000900465ffffffffffff1661156e5760405162461bcd60e51b815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152606401610629565b60018201544264010000000090910465ffffffffffff1611156115d35760405162461bcd60e51b815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152606401610629565b60018201805469ffffffffffffffffffff191690558154600160781b600160e81b0319168255604080516001600160a01b03851681526020810183905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda3910160405180910390a26000836001600160a01b03168260405160006040518083038185875af1925050503d806000811461168a576040519150601f19603f3d011682016040523d82523d6000602084013e61168f565b606091505b5050905080610cf65760405162461bcd60e51b815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152606401610629565b6116e861303b565b6116f1856123a5565b60008061170060008885611de5565b915091506000611710838361247f565b905061171b43600052565b600061172960008a8761216c565b905061173443600052565b600060606001600160a01b038a16156117aa57896001600160a01b03168989604051611761929190613a89565b6000604051808303816000865af19150503d806000811461179e576040519150601f19603f3d011682016040523d82523d6000602084013e6117a3565b606091505b5090925090505b866080015183856020015186604001518585604051630116f59360e71b815260040161062996959493929190613a99565b6117e361303b565b6117ec826123a5565b6000806117fb60008585611de5565b915091506000611812846000015160a0015161254b565b8451519091506000906118249061254b565b9050611843604051806040016040528060008152602001600081525090565b36600061185360408a018a6137ab565b90925090506000601482101561186a576000611885565b6118786014600084866139d3565b611881916139fd565b60601c5b90506118908161254b565b935050505060006118a1868661247f565b9050600081600001519050600060016001600160a01b0316826001600160a01b031614905060006040518060c001604052808b6080015181526020018b6040015181526020018315158152602001856020015165ffffffffffff168152602001856040015165ffffffffffff16815260200161191e8c6060015190565b905290506001600160a01b0383161580159061194457506001600160a01b038316600114155b156119965760006040518060400160405280856001600160a01b0316815260200161196e8661254b565b81525090508187878a84604051633ebb2d3960e21b8152600401610629959493929190613b3b565b8086868960405163e0cff05f60e01b81526004016106299493929190613bbb565b6001600160a01b038216600090815260208190526040812080549091906119e89084906001600160701b031661366d565b90506001600160701b03811115611a345760405162461bcd60e51b815260206004820152601060248201526f6465706f736974206f766572666c6f7760801b6044820152606401610629565b81546001600160701b0319166001600160701b03919091161790555050565b6000806000845160208601878987f195945050505050565b60603d82811115611a795750815b604051602082018101604052818152816000602083013e9392505050565b6000805a855190915060009081611aad8261259a565b60a08301519091506001600160a01b038116611acc5782519350611c73565b809350600088511115611c7357868202955060028a6002811115611af257611af2613c12565b14611b6457606083015160405163a9a2340960e01b81526001600160a01b0383169163a9a2340991611b2c908e908d908c90600401613c28565b600060405180830381600088803b158015611b4657600080fd5b5087f1158015611b5a573d6000803e3d6000fd5b5050505050611c73565b606083015160405163a9a2340960e01b81526001600160a01b0383169163a9a2340991611b99908e908d908c90600401613c28565b600060405180830381600088803b158015611bb357600080fd5b5087f193505050508015611bc5575060015b611c7357611bd1613c6f565b806308c379a003611c2a5750611be5613c8b565b80611bf05750611c2c565b8b81604051602001611c029190613d14565b60408051601f1981840301815290829052631101335b60e11b825261062992916004016136e9565b505b8a604051631101335b60e11b81526004016106299181526040602082018190526012908201527110504d4c081c1bdcdd13dc081c995d995c9d60721b606082015260800190565b5a85038701965081870295508589604001511015611cdc578a604051631101335b60e11b815260040161062991815260406020808301829052908201527f414135312070726566756e642062656c6f772061637475616c476173436f7374606082015260800190565b6040890151869003611cee85826119b7565b6000808c6002811115611d0357611d03613c12565b1490508460a001516001600160a01b031685600001516001600160a01b03168c602001517f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f8860200151858d8f604051611d76949392919093845291151560208401526040830152606082015260800190565b60405180910390a45050505050505095945050505050565b6002805403611ddf5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610629565b60028055565b60008060005a8451909150611dfa86826125ca565b611e038661133d565b6020860152604081015160608201516080830151171760e087013517610100870135176effffffffffffffffffffffffffffff811115611e855760405162461bcd60e51b815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152606401610629565b600080611e91846126c3565b9050611e9f8a8a8a84612710565b85516020870151919950919350611eb69190612948565b611f0c5789604051631101335b60e11b8152600401610629918152604060208201819052601a908201527f4141323520696e76616c6964206163636f756e74206e6f6e6365000000000000606082015260800190565b611f1543600052565b60a08401516060906001600160a01b031615611f3d57611f388b8b8b8587612995565b975090505b60005a87039050808b60a001351015611fa2578b604051631101335b60e11b8152600401610629918152604060208201819052601e908201527f41413430206f76657220766572696669636174696f6e4761734c696d69740000606082015260800190565b60408a018390528160608b015260c08b01355a8803018a608001818152505050505050505050935093915050565b600080611fdc85612bb8565b91509150816001600160a01b0316836001600160a01b0316146120425785604051631101335b60e11b81526004016106299181526040602082018190526014908201527320a0991a1039b4b3b730ba3ab9329032b93937b960611b606082015260800190565b801561209a5785604051631101335b60e11b81526004016106299181526040602082018190526017908201527f414132322065787069726564206f72206e6f7420647565000000000000000000606082015260800190565b60006120a585612bb8565b925090506001600160a01b038116156121015786604051631101335b60e11b81526004016106299181526040602082018190526014908201527320a0999a1039b4b3b730ba3ab9329032b93937b960611b606082015260800190565b81156121635786604051631101335b60e11b81526004016106299181526040602082018190526021908201527f41413332207061796d61737465722065787069726564206f72206e6f742064756060820152606560f81b608082015260a00190565b50505050505050565b6000805a9050600061217f846060015190565b905030631d73275661219460608801886137ab565b87856040518563ffffffff1660e01b81526004016121b59493929190613d52565b6020604051808303816000875af19250505080156121f0575060408051601f3d908101601f191682019092526121ed91810190613e05565b60015b61228757600060206000803e50600051632152215360e01b81016122525786604051631101335b60e11b8152600401610629918152604060208201819052600f908201526e41413935206f7574206f662067617360881b606082015260800190565b600085608001515a6122649086613739565b61226e919061366d565b905061227e886002888685611a97565b9450505061228a565b92505b50509392505050565b6001600160a01b0382166122e95760405162461bcd60e51b815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152606401610629565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612336576040519150601f19603f3d011682016040523d82523d6000602084013e61233b565b606091505b5050905080610b7b5760405162461bcd60e51b815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152606401610629565b600061239782612c0b565b805190602001209050919050565b3063957122ab6123b860408401846137ab565b6123c560208601866134c7565b6123d36101208701876137ab565b6040518663ffffffff1660e01b81526004016123f3959493929190613e1e565b60006040518083038186803b15801561240b57600080fd5b505afa92505050801561241c575060015b61247c57612428613c6f565b806308c379a003612470575061243c613c8b565b806124475750612472565b80511561246c57600081604051631101335b60e11b81526004016106299291906136e9565b5050565b505b3d6000803e3d6000fd5b50565b60408051606081018252600080825260208201819052918101829052906124a584612cde565b905060006124b284612cde565b82519091506001600160a01b0381166124c9575080515b602080840151604080860151928501519085015191929165ffffffffffff80831690851610156124f7578193505b8065ffffffffffff168365ffffffffffff161115612513578092505b5050604080516060810182526001600160a01b03909416845265ffffffffffff92831660208501529116908201529250505092915050565b604080518082018252600080825260208083018281526001600160a01b03959095168252819052919091208054600160781b90046001600160701b031682526001015463ffffffff1690915290565b60c081015160e0820151600091908082036125b6575092915050565b6125c282488301612d4f565b949350505050565b6125d760208301836134c7565b6001600160a01b0316815260208083013590820152608080830135604083015260a0830135606083015260c0808401359183019190915260e08084013591830191909152610100830135908201523660006126366101208501856137ab565b909250905080156126b65760148110156126925760405162461bcd60e51b815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152606401610629565b6126a06014600083856139d3565b6126a9916139fd565b60601c60a0840152610cf6565b600060a084015250505050565b60a081015160009081906001600160a01b03166126e15760016126e4565b60035b60ff16905060008360800151828560600151028560400151010190508360c00151810292505050919050565b60008060005a8551805191925090612735898861273060408c018c6137ab565b612d67565b60a082015161274343600052565b60006001600160a01b03821661278b576001600160a01b0383166000908152602081905260409020546001600160701b031688811161278457808903612787565b60005b9150505b606084015160208a0151604051633a871cdd60e01b81526001600160a01b03861692633a871cdd9290916127c5918f918790600401613e54565b60206040518083038160008887f193505050508015612801575060408051601f3d908101601f191682019092526127fe91810190613e05565b60015b61288b5761280d613c6f565b806308c379a00361283e5750612821613c8b565b8061282c5750612840565b8b81604051602001611c029190613e79565b505b8a604051631101335b60e11b8152600401610629918152604060208201819052601690820152754141323320726576657274656420286f72204f4f472960501b606082015260800190565b95506001600160a01b038216612935576001600160a01b038316600090815260208190526040902080546001600160701b0316808a1115612918578c604051631101335b60e11b81526004016106299181526040602082018190526017908201527f41413231206469646e2774207061792070726566756e64000000000000000000606082015260800190565b81546001600160701b031916908a90036001600160701b03161790555b5a85039650505050505094509492505050565b6001600160a01b038216600090815260016020908152604080832084821c80855292528220805484916001600160401b03831691908561298783613680565b909155501495945050505050565b825160608181015190916000918481116129f15760405162461bcd60e51b815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152606401610629565b60a08201516001600160a01b038116600090815260208190526040902080548784039291906001600160701b031689811015612a79578c604051631101335b60e11b8152600401610629918152604060208201819052601e908201527f41413331207061796d6173746572206465706f73697420746f6f206c6f770000606082015260800190565b8981038260000160006101000a8154816001600160701b0302191690836001600160701b03160217905550826001600160a01b031663f465c77e858e8e602001518e6040518563ffffffff1660e01b8152600401612ad993929190613e54565b60006040518083038160008887f193505050508015612b1a57506040513d6000823e601f3d908101601f19168201604052612b179190810190613eb0565b60015b612ba457612b26613c6f565b806308c379a003612b575750612b3a613c8b565b80612b455750612b59565b8d81604051602001611c029190613f3b565b505b8c604051631101335b60e11b8152600401610629918152604060208201819052601690820152754141333320726576657274656420286f72204f4f472960501b606082015260800190565b909e909d509b505050505050505050505050565b60008082600003612bce57506000928392509050565b6000612bd984612cde565b9050806040015165ffffffffffff16421180612c005750806020015165ffffffffffff1642105b905194909350915050565b6060813560208301356000612c2b612c2660408701876137ab565b613028565b90506000612c3f612c2660608801886137ab565b9050608086013560a087013560c088013560e08901356101008a01356000612c6e612c266101208e018e6137ab565b604080516001600160a01b039c909c1660208d01528b81019a909a5260608b019890985250608089019590955260a088019390935260c087019190915260e08601526101008501526101208401526101408084019190915281518084039091018152610160909201905292915050565b60408051606081018252600080825260208201819052918101919091528160a081901c65ffffffffffff8116600003612d1a575065ffffffffffff5b604080516060810182526001600160a01b03909316835260d09490941c602083015265ffffffffffff16928101929092525090565b6000818310612d5e5781612d60565b825b9392505050565b8015610cf6578251516001600160a01b0381163b15612dd25784604051631101335b60e11b8152600401610629918152604060208201819052601f908201527f414131302073656e64657220616c726561647920636f6e737472756374656400606082015260800190565b835160600151604051632b870d1b60e11b81526000916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163570e1a369190612e2a9088908890600401613a32565b60206040518083038160008887f1158015612e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612e6e9190613a46565b90506001600160a01b038116612ed05785604051631101335b60e11b8152600401610629918152604060208201819052601b908201527f4141313320696e6974436f6465206661696c6564206f72204f4f470000000000606082015260800190565b816001600160a01b0316816001600160a01b031614612f3a5785604051631101335b60e11b815260040161062991815260406020808301829052908201527f4141313420696e6974436f6465206d7573742072657475726e2073656e646572606082015260800190565b806001600160a01b03163b600003612f9d5785604051631101335b60e11b815260040161062991815260406020808301829052908201527f4141313520696e6974436f6465206d757374206372656174652073656e646572606082015260800190565b6000612fac60148286886139d3565b612fb5916139fd565b60601c9050826001600160a01b031686602001517fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d83896000015160a001516040516130179291906001600160a01b0392831681529116602082015260400190565b60405180910390a350505050505050565b6000604051828085833790209392505050565b6040518060a001604052806130a060405180610100016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160008152602001600081525090565b8152602001600080191681526020016000815260200160008152602001600081525090565b6000602082840312156130d757600080fd5b813563ffffffff81168114612d6057600080fd5b80356001600160c01b038116811461310257600080fd5b919050565b60006020828403121561311957600080fd5b612d60826130eb565b6001600160a01b038116811461247c57600080fd5b803561310281613122565b6000806040838503121561315557600080fd5b823561316081613122565b915061316e602084016130eb565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b60a081018181106001600160401b03821117156131ac576131ac613177565b60405250565b61010081018181106001600160401b03821117156131ac576131ac613177565b601f8201601f191681016001600160401b03811182821017156131f7576131f7613177565b6040525050565b60006001600160401b0382111561321757613217613177565b50601f01601f191660200190565b600081830361018081121561323957600080fd5b6040516132458161318d565b8092506101008083121561325857600080fd5b6040519250613266836131b2565b61326f85613137565b8352602085013560208401526040850135604084015260608501356060840152608085013560808401526132a560a08601613137565b60a084015260c085013560c084015260e085013560e084015282825280850135602083015250610120840135604082015261014084013560608201526101608401356080820152505092915050565b60008083601f84011261330657600080fd5b5081356001600160401b0381111561331d57600080fd5b60208301915083602082850101111561333557600080fd5b9250929050565b6000806000806101c0858703121561335357600080fd5b84356001600160401b038082111561336a57600080fd5b818701915087601f83011261337e57600080fd5b8135613389816131fe565b60405161339682826131d2565b8281528a60208487010111156133ab57600080fd5b826020860160208301376000602084830101528098505050506133d18860208901613225565b94506101a08701359150808211156133e857600080fd5b506133f5878288016132f4565b95989497509550505050565b60008083601f84011261341357600080fd5b5081356001600160401b0381111561342a57600080fd5b6020830191508360208260051b850101111561333557600080fd5b60008060006040848603121561345a57600080fd5b83356001600160401b0381111561347057600080fd5b61347c86828701613401565b909450925050602084013561349081613122565b809150509250925092565b600080604083850312156134ae57600080fd5b82356134b981613122565b946020939093013593505050565b6000602082840312156134d957600080fd5b8135612d6081613122565b6000806000806000606086880312156134fc57600080fd5b85356001600160401b038082111561351357600080fd5b61351f89838a016132f4565b90975095506020880135915061353482613122565b9093506040870135908082111561354a57600080fd5b50613557888289016132f4565b969995985093965092949392505050565b6000806020838503121561357b57600080fd5b82356001600160401b0381111561359157600080fd5b61359d858286016132f4565b90969095509350505050565b600061016082840312156135bc57600080fd5b50919050565b6000602082840312156135d457600080fd5b81356001600160401b038111156135ea57600080fd5b6125c2848285016135a9565b6000806000806060858703121561360c57600080fd5b84356001600160401b038082111561362357600080fd5b61362f888389016135a9565b95506020870135915061364182613122565b909350604086013590808211156133e857600080fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610d3c57610d3c613657565b60006001820161369257613692613657565b5060010190565b60005b838110156136b457818101518382015260200161369c565b50506000910152565b600081518084526136d5816020860160208601613699565b601f01601f19169290920160200192915050565b8281526040602082015260006125c260408301846136bd565b634e487b7160e01b600052603260045260246000fd5b6000823561015e1983360301811261372f57600080fd5b9190910192915050565b81810381811115610d3c57610d3c613657565b60008235605e1983360301811261372f57600080fd5b6000808335601e1984360301811261377957600080fd5b8301803591506001600160401b0382111561379357600080fd5b6020019150600581901b360382131561333557600080fd5b6000808335601e198436030181126137c257600080fd5b8301803591506001600160401b038211156137dc57600080fd5b60200191503681900382131561333557600080fd5b6000808335601e1984360301811261380857600080fd5b83016020810192503590506001600160401b0381111561382757600080fd5b80360382131561333557600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b600061016061387e8461387185613137565b6001600160a01b03169052565b6020830135602085015261389560408401846137f1565b8260408701526138a88387018284613836565b925050506138b960608401846137f1565b85830360608701526138cc838284613836565b925050506080830135608085015260a083013560a085015260c083013560c085015260e083013560e0850152610100808401358186015250610120613913818501856137f1565b86840383880152613925848284613836565b9350505050610140613939818501856137f1565b8684038388015261394b848284613836565b979650505050505050565b6040808252810184905260006060600586901b830181019083018783805b898110156139bc57868503605f190184528235368c900361015e1901811261399a578283fd5b6139a6868d830161385f565b9550506020938401939290920191600101613974565b50505050828103602084015261394b818587613836565b600080858511156139e357600080fd5b838611156139f057600080fd5b5050820193919092039150565b6bffffffffffffffffffffffff198135818116916014851015613a2a5780818660140360031b1b83161692505b505092915050565b6020815260006125c2602083018486613836565b600060208284031215613a5857600080fd5b8151612d6081613122565b65ffffffffffff818116838216019080821115613a8257613a82613657565b5092915050565b8183823760009101908152919050565b868152856020820152600065ffffffffffff8087166040840152808616606084015250831515608083015260c060a0830152613ad860c08301846136bd565b98975050505050505050565b80518252602081015160208301526040810151151560408301526000606082015165ffffffffffff8082166060860152806080850151166080860152505060a082015160c060a08501526125c260c08501826136bd565b6000610140808352613b4f81840189613ae4565b915050613b69602083018780518252602090810151910152565b845160608301526020948501516080830152835160a08301529284015160c082015281516001600160a01b031660e0820152908301518051610100830152909201516101209092019190915292915050565b60e081526000613bce60e0830187613ae4565b9050613be7602083018680518252602090810151910152565b8351606083015260208401516080830152825160a0830152602083015160c083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b600060038510613c4857634e487b7160e01b600052602160045260246000fd5b84825260606020830152613c5f60608301856136bd565b9050826040830152949350505050565b600060033d1115613c885760046000803e5060005160e01c5b90565b600060443d1015613c995790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715613cc857505050505090565b8285019150815181811115613ce05750505050505090565b843d8701016020828501011115613cfa5750505050505090565b613d09602082860101876131d2565b509095945050505050565b75020a09a98103837b9ba27b8103932bb32b93a32b21d160551b815260008251613d45816016850160208701613699565b9190910160160192915050565b60006101c0808352613d678184018789613836565b9050845160018060a01b03808251166020860152602082015160408601526040820151606086015260608201516080860152608082015160a08601528060a08301511660c08601525060c081015160e085015260e08101516101008501525060208501516101208401526040850151610140840152606085015161016084015260808501516101808401528281036101a084015261394b81856136bd565b600060208284031215613e1757600080fd5b5051919050565b606081526000613e32606083018789613836565b6001600160a01b03861660208401528281036040840152613ad8818587613836565b606081526000613e67606083018661385f565b60208301949094525060400152919050565b6e020a09919903932bb32b93a32b21d1608d1b815260008251613ea381600f850160208701613699565b91909101600f0192915050565b60008060408385031215613ec357600080fd5b82516001600160401b03811115613ed957600080fd5b8301601f81018513613eea57600080fd5b8051613ef5816131fe565b604051613f0282826131d2565b828152876020848601011115613f1757600080fd5b613f28836020830160208701613699565b6020969096015195979596505050505050565b6e020a09999903932bb32b93a32b21d1608d1b815260008251613ea381600f85016020870161369956fea2646970667358221220bc5c14ed3ec926af1ab28e2fd999437beb980f78c0fe5ff3c1e6bd7d67fe265c64736f6c63430008110033608060405234801561001057600080fd5b506101f3806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063570e1a3614610030575b600080fd5b61004361003e3660046100ec565b61005f565b6040516001600160a01b03909116815260200160405180910390f35b60008061006f601482858761015e565b61007891610188565b60601c9050600061008c846014818861015e565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525084519495509360209350849250905082850182875af190506000519350806100e357600093505b50505092915050565b600080602083850312156100ff57600080fd5b823567ffffffffffffffff8082111561011757600080fd5b818501915085601f83011261012b57600080fd5b81358181111561013a57600080fd5b86602082850101111561014c57600080fd5b60209290920196919550909350505050565b6000808585111561016e57600080fd5b8386111561017b57600080fd5b5050820193919092039150565b6bffffffffffffffffffffffff1981358181169160148510156101b55780818660140360031b1b83161692505b50509291505056fea2646970667358221220b5656449fb60570ea8cd9e36b4894a1f42b3446a8305554bddfc0df85c8a89c764736f6c63430008110033
Deployed Bytecode
0x6080604052600436106101235760003560e01c80638f41ec5a116100a0578063bb9fe6bf11610064578063bb9fe6bf1461043a578063c23a5cea1461044f578063d6383f941461046f578063ee2194231461048f578063fc7e286d146104af57600080fd5b80638f41ec5a146103b2578063957122ab146103c75780639b249f69146103e7578063a619353114610407578063b760faf91461042757600080fd5b8063205c2878116100e7578063205c2878146101f657806335567e1a146102165780634b1d7cf5146102365780635287ce121461025657806370a082311461037357600080fd5b80630396cb60146101385780630bd28e3b1461014b5780631b2e01b81461016b5780631d732756146101b65780631fad948c146101d657600080fd5b366101335761013133610564565b005b600080fd5b6101316101463660046130c5565b6105cb565b34801561015757600080fd5b50610131610166366004613107565b61085a565b34801561017757600080fd5b506101a3610186366004613142565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b3480156101c257600080fd5b506101a36101d136600461333c565b610891565b3480156101e257600080fd5b506101316101f1366004613445565b610a04565b34801561020257600080fd5b5061013161021136600461349b565b610b80565b34801561022257600080fd5b506101a3610231366004613142565b610cfc565b34801561024257600080fd5b50610131610251366004613445565b610d42565b34801561026257600080fd5b5061031b6102713660046134c7565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506001600160a01b031660009081526020818152604091829020825160a08101845281546001600160701b038082168352600160701b820460ff16151594830194909452600160781b90049092169282019290925260019091015463ffffffff81166060830152640100000000900465ffffffffffff16608082015290565b6040805182516001600160701b03908116825260208085015115159083015283830151169181019190915260608083015163ffffffff169082015260809182015165ffffffffffff169181019190915260a0016101ad565b34801561037f57600080fd5b506101a361038e3660046134c7565b6001600160a01b03166000908152602081905260409020546001600160701b031690565b3480156103be57600080fd5b506101a3600181565b3480156103d357600080fd5b506101316103e23660046134e4565b611185565b3480156103f357600080fd5b50610131610402366004613568565b611282565b34801561041357600080fd5b506101a36104223660046135c2565b61133d565b6101316104353660046134c7565b610564565b34801561044657600080fd5b5061013161137f565b34801561045b57600080fd5b5061013161046a3660046134c7565b6114a8565b34801561047b57600080fd5b5061013161048a3660046135f6565b6116e0565b34801561049b57600080fd5b506101316104aa3660046135c2565b6117db565b3480156104bb57600080fd5b5061051e6104ca3660046134c7565b600060208190529081526040902080546001909101546001600160701b0380831692600160701b810460ff1692600160781b9091049091169063ffffffff811690640100000000900465ffffffffffff1685565b604080516001600160701b0396871681529415156020860152929094169183019190915263ffffffff16606082015265ffffffffffff909116608082015260a0016101ad565b61056e81346119b7565b6001600160a01b03811660008181526020818152604091829020805492516001600160701b03909316835292917f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c491015b60405180910390a25050565b33600090815260208190526040902063ffffffff82166106325760405162461bcd60e51b815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c617900000000000060448201526064015b60405180910390fd5b600181015463ffffffff90811690831610156106905760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152606401610629565b80546000906106b0903490600160781b90046001600160701b031661366d565b9050600081116106f75760405162461bcd60e51b81526020600482015260126024820152711b9bc81cdd185ad9481cdc1958da599a595960721b6044820152606401610629565b6001600160701b0381111561073f5760405162461bcd60e51b815260206004820152600e60248201526d7374616b65206f766572666c6f7760901b6044820152606401610629565b6040805160a08101825283546001600160701b0390811682526001602080840182815286841685870190815263ffffffff808b16606088019081526000608089018181523380835296829052908a902098518954955194518916600160781b02600160781b600160e81b0319951515600160701b026effffffffffffffffffffffffffffff199097169190991617949094179290921695909517865551949092018054925165ffffffffffff166401000000000269ffffffffffffffffffff19909316949093169390931717905590517fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c019061084d908490879091825263ffffffff16602082015260400190565b60405180910390a2505050565b3360009081526001602090815260408083206001600160c01b0385168452909152812080549161088983613680565b919050555050565b6000805a90503330146108e65760405162461bcd60e51b815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152606401610629565b8451604081015160608201518101611388015a10156109105763deaddead60e01b60005260206000fd5b8751600090156109a457600061092d846000015160008c86611a53565b9050806109a2576000610941610800611a6b565b80519091501561099c5784600001516001600160a01b03168a602001517f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a2018760200151846040516109939291906136e9565b60405180910390a35b60019250505b505b600088608001515a86030190506109f66000838b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250611a97915050565b9a9950505050505050505050565b610a0c611d8e565b816000816001600160401b03811115610a2757610a27613177565b604051908082528060200260200182016040528015610a6057816020015b610a4d61303b565b815260200190600190039081610a455790505b50905060005b82811015610ad9576000828281518110610a8257610a82613702565b60200260200101519050600080610abd848a8a87818110610aa557610aa5613702565b9050602002810190610ab79190613718565b85611de5565b91509150610ace8483836000611fd0565b505050600101610a66565b506040516000907fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972908290a160005b83811015610b6357610b5781888884818110610b2657610b26613702565b9050602002810190610b389190613718565b858481518110610b4a57610b4a613702565b602002602001015161216c565b90910190600101610b08565b50610b6e8482612293565b505050610b7b6001600255565b505050565b33600090815260208190526040902080546001600160701b0316821115610be95760405162461bcd60e51b815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152606401610629565b8054610bff9083906001600160701b0316613739565b81546001600160701b0319166001600160701b0391909116178155604080516001600160a01b03851681526020810184905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb910160405180910390a26000836001600160a01b03168360405160006040518083038185875af1925050503d8060008114610cab576040519150601f19603f3d011682016040523d82523d6000602084013e610cb0565b606091505b5050905080610cf65760405162461bcd60e51b81526020600482015260126024820152716661696c656420746f20776974686472617760701b6044820152606401610629565b50505050565b6001600160a01b03821660009081526001602090815260408083206001600160c01b038516845290915290819020549082901b67ffffffffffffffff1916175b92915050565b610d4a611d8e565b816000805b82811015610ebe5736868683818110610d6a57610d6a613702565b9050602002810190610d7c919061374c565b9050366000610d8b8380613762565b90925090506000610da260408501602086016134c7565b90506000196001600160a01b03821601610dfe5760405162461bcd60e51b815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152606401610629565b6001600160a01b03811615610e9b576001600160a01b03811663e3563a4f8484610e2b60408901896137ab565b6040518563ffffffff1660e01b8152600401610e4a9493929190613956565b60006040518083038186803b158015610e6257600080fd5b505afa925050508015610e73575060015b610e9b5760405163086a9f7560e41b81526001600160a01b0382166004820152602401610629565b610ea5828761366d565b9550505050508080610eb690613680565b915050610d4f565b506000816001600160401b03811115610ed957610ed9613177565b604051908082528060200260200182016040528015610f1257816020015b610eff61303b565b815260200190600190039081610ef75790505b506040519091507fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f97290600090a16000805b848110156110275736888883818110610f5e57610f5e613702565b9050602002810190610f70919061374c565b9050366000610f7f8380613762565b90925090506000610f9660408501602086016134c7565b90508160005b8181101561100e576000898981518110610fb857610fb8613702565b60200260200101519050600080610fdb8b898987818110610aa557610aa5613702565b91509150610feb84838389611fd0565b8a610ff581613680565b9b5050505050808061100690613680565b915050610f9c565b505050505050808061101f90613680565b915050610f43565b50600080915060005b85811015611140573689898381811061104b5761104b613702565b905060200281019061105d919061374c565b905061106f60408201602083016134c7565b6001600160a01b03167f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d60405160405180910390a23660006110b18380613762565b90925090508060005b81811015611128576110fc888585848181106110d8576110d8613702565b90506020028101906110ea9190613718565b8b8b81518110610b4a57610b4a613702565b611106908861366d565b96508761111281613680565b985050808061112090613680565b9150506110ba565b5050505050808061113890613680565b915050611030565b506040516000907f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d908290a26111768682612293565b5050505050610b7b6001600255565b8315801561119b57506001600160a01b0383163b155b156111e85760405162461bcd60e51b815260206004820152601960248201527f41413230206163636f756e74206e6f74206465706c6f796564000000000000006044820152606401610629565b601481106112605760006111ff60148284866139d3565b611208916139fd565b60601c9050803b60000361125e5760405162461bcd60e51b815260206004820152601b60248201527f41413330207061796d6173746572206e6f74206465706c6f79656400000000006044820152606401610629565b505b60405162461bcd60e51b81526020600482015260006024820152604401610629565b604051632b870d1b60e11b81526000906001600160a01b037f000000000000000000000000dc319bc5b872fc39390546c1b6f68bc574bb4a5e169063570e1a36906112d39086908690600401613a32565b6020604051808303816000875af11580156112f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113169190613a46565b604051633653dc0360e11b81526001600160a01b0382166004820152909150602401610629565b60006113488261238c565b6040805160208101929092523090820152466060820152608001604051602081830303815290604052805190602001209050919050565b3360009081526020819052604081206001810154909163ffffffff90911690036113d85760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081cdd185ad95960b21b6044820152606401610629565b8054600160701b900460ff166114245760405162461bcd60e51b8152602060048201526011602482015270616c726561647920756e7374616b696e6760781b6044820152606401610629565b600181015460009061143c9063ffffffff1642613a63565b60018301805469ffffffffffff00000000191664010000000065ffffffffffff841690810291909117909155835460ff60701b1916845560405190815290915033907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a906020016105bf565b3360009081526020819052604090208054600160781b90046001600160701b03168061150d5760405162461bcd60e51b81526020600482015260146024820152734e6f207374616b6520746f20776974686472617760601b6044820152606401610629565b6001820154640100000000900465ffffffffffff1661156e5760405162461bcd60e51b815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152606401610629565b60018201544264010000000090910465ffffffffffff1611156115d35760405162461bcd60e51b815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152606401610629565b60018201805469ffffffffffffffffffff191690558154600160781b600160e81b0319168255604080516001600160a01b03851681526020810183905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda3910160405180910390a26000836001600160a01b03168260405160006040518083038185875af1925050503d806000811461168a576040519150601f19603f3d011682016040523d82523d6000602084013e61168f565b606091505b5050905080610cf65760405162461bcd60e51b815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152606401610629565b6116e861303b565b6116f1856123a5565b60008061170060008885611de5565b915091506000611710838361247f565b905061171b43600052565b600061172960008a8761216c565b905061173443600052565b600060606001600160a01b038a16156117aa57896001600160a01b03168989604051611761929190613a89565b6000604051808303816000865af19150503d806000811461179e576040519150601f19603f3d011682016040523d82523d6000602084013e6117a3565b606091505b5090925090505b866080015183856020015186604001518585604051630116f59360e71b815260040161062996959493929190613a99565b6117e361303b565b6117ec826123a5565b6000806117fb60008585611de5565b915091506000611812846000015160a0015161254b565b8451519091506000906118249061254b565b9050611843604051806040016040528060008152602001600081525090565b36600061185360408a018a6137ab565b90925090506000601482101561186a576000611885565b6118786014600084866139d3565b611881916139fd565b60601c5b90506118908161254b565b935050505060006118a1868661247f565b9050600081600001519050600060016001600160a01b0316826001600160a01b031614905060006040518060c001604052808b6080015181526020018b6040015181526020018315158152602001856020015165ffffffffffff168152602001856040015165ffffffffffff16815260200161191e8c6060015190565b905290506001600160a01b0383161580159061194457506001600160a01b038316600114155b156119965760006040518060400160405280856001600160a01b0316815260200161196e8661254b565b81525090508187878a84604051633ebb2d3960e21b8152600401610629959493929190613b3b565b8086868960405163e0cff05f60e01b81526004016106299493929190613bbb565b6001600160a01b038216600090815260208190526040812080549091906119e89084906001600160701b031661366d565b90506001600160701b03811115611a345760405162461bcd60e51b815260206004820152601060248201526f6465706f736974206f766572666c6f7760801b6044820152606401610629565b81546001600160701b0319166001600160701b03919091161790555050565b6000806000845160208601878987f195945050505050565b60603d82811115611a795750815b604051602082018101604052818152816000602083013e9392505050565b6000805a855190915060009081611aad8261259a565b60a08301519091506001600160a01b038116611acc5782519350611c73565b809350600088511115611c7357868202955060028a6002811115611af257611af2613c12565b14611b6457606083015160405163a9a2340960e01b81526001600160a01b0383169163a9a2340991611b2c908e908d908c90600401613c28565b600060405180830381600088803b158015611b4657600080fd5b5087f1158015611b5a573d6000803e3d6000fd5b5050505050611c73565b606083015160405163a9a2340960e01b81526001600160a01b0383169163a9a2340991611b99908e908d908c90600401613c28565b600060405180830381600088803b158015611bb357600080fd5b5087f193505050508015611bc5575060015b611c7357611bd1613c6f565b806308c379a003611c2a5750611be5613c8b565b80611bf05750611c2c565b8b81604051602001611c029190613d14565b60408051601f1981840301815290829052631101335b60e11b825261062992916004016136e9565b505b8a604051631101335b60e11b81526004016106299181526040602082018190526012908201527110504d4c081c1bdcdd13dc081c995d995c9d60721b606082015260800190565b5a85038701965081870295508589604001511015611cdc578a604051631101335b60e11b815260040161062991815260406020808301829052908201527f414135312070726566756e642062656c6f772061637475616c476173436f7374606082015260800190565b6040890151869003611cee85826119b7565b6000808c6002811115611d0357611d03613c12565b1490508460a001516001600160a01b031685600001516001600160a01b03168c602001517f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f8860200151858d8f604051611d76949392919093845291151560208401526040830152606082015260800190565b60405180910390a45050505050505095945050505050565b6002805403611ddf5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610629565b60028055565b60008060005a8451909150611dfa86826125ca565b611e038661133d565b6020860152604081015160608201516080830151171760e087013517610100870135176effffffffffffffffffffffffffffff811115611e855760405162461bcd60e51b815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152606401610629565b600080611e91846126c3565b9050611e9f8a8a8a84612710565b85516020870151919950919350611eb69190612948565b611f0c5789604051631101335b60e11b8152600401610629918152604060208201819052601a908201527f4141323520696e76616c6964206163636f756e74206e6f6e6365000000000000606082015260800190565b611f1543600052565b60a08401516060906001600160a01b031615611f3d57611f388b8b8b8587612995565b975090505b60005a87039050808b60a001351015611fa2578b604051631101335b60e11b8152600401610629918152604060208201819052601e908201527f41413430206f76657220766572696669636174696f6e4761734c696d69740000606082015260800190565b60408a018390528160608b015260c08b01355a8803018a608001818152505050505050505050935093915050565b600080611fdc85612bb8565b91509150816001600160a01b0316836001600160a01b0316146120425785604051631101335b60e11b81526004016106299181526040602082018190526014908201527320a0991a1039b4b3b730ba3ab9329032b93937b960611b606082015260800190565b801561209a5785604051631101335b60e11b81526004016106299181526040602082018190526017908201527f414132322065787069726564206f72206e6f7420647565000000000000000000606082015260800190565b60006120a585612bb8565b925090506001600160a01b038116156121015786604051631101335b60e11b81526004016106299181526040602082018190526014908201527320a0999a1039b4b3b730ba3ab9329032b93937b960611b606082015260800190565b81156121635786604051631101335b60e11b81526004016106299181526040602082018190526021908201527f41413332207061796d61737465722065787069726564206f72206e6f742064756060820152606560f81b608082015260a00190565b50505050505050565b6000805a9050600061217f846060015190565b905030631d73275661219460608801886137ab565b87856040518563ffffffff1660e01b81526004016121b59493929190613d52565b6020604051808303816000875af19250505080156121f0575060408051601f3d908101601f191682019092526121ed91810190613e05565b60015b61228757600060206000803e50600051632152215360e01b81016122525786604051631101335b60e11b8152600401610629918152604060208201819052600f908201526e41413935206f7574206f662067617360881b606082015260800190565b600085608001515a6122649086613739565b61226e919061366d565b905061227e886002888685611a97565b9450505061228a565b92505b50509392505050565b6001600160a01b0382166122e95760405162461bcd60e51b815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152606401610629565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612336576040519150601f19603f3d011682016040523d82523d6000602084013e61233b565b606091505b5050905080610b7b5760405162461bcd60e51b815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152606401610629565b600061239782612c0b565b805190602001209050919050565b3063957122ab6123b860408401846137ab565b6123c560208601866134c7565b6123d36101208701876137ab565b6040518663ffffffff1660e01b81526004016123f3959493929190613e1e565b60006040518083038186803b15801561240b57600080fd5b505afa92505050801561241c575060015b61247c57612428613c6f565b806308c379a003612470575061243c613c8b565b806124475750612472565b80511561246c57600081604051631101335b60e11b81526004016106299291906136e9565b5050565b505b3d6000803e3d6000fd5b50565b60408051606081018252600080825260208201819052918101829052906124a584612cde565b905060006124b284612cde565b82519091506001600160a01b0381166124c9575080515b602080840151604080860151928501519085015191929165ffffffffffff80831690851610156124f7578193505b8065ffffffffffff168365ffffffffffff161115612513578092505b5050604080516060810182526001600160a01b03909416845265ffffffffffff92831660208501529116908201529250505092915050565b604080518082018252600080825260208083018281526001600160a01b03959095168252819052919091208054600160781b90046001600160701b031682526001015463ffffffff1690915290565b60c081015160e0820151600091908082036125b6575092915050565b6125c282488301612d4f565b949350505050565b6125d760208301836134c7565b6001600160a01b0316815260208083013590820152608080830135604083015260a0830135606083015260c0808401359183019190915260e08084013591830191909152610100830135908201523660006126366101208501856137ab565b909250905080156126b65760148110156126925760405162461bcd60e51b815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152606401610629565b6126a06014600083856139d3565b6126a9916139fd565b60601c60a0840152610cf6565b600060a084015250505050565b60a081015160009081906001600160a01b03166126e15760016126e4565b60035b60ff16905060008360800151828560600151028560400151010190508360c00151810292505050919050565b60008060005a8551805191925090612735898861273060408c018c6137ab565b612d67565b60a082015161274343600052565b60006001600160a01b03821661278b576001600160a01b0383166000908152602081905260409020546001600160701b031688811161278457808903612787565b60005b9150505b606084015160208a0151604051633a871cdd60e01b81526001600160a01b03861692633a871cdd9290916127c5918f918790600401613e54565b60206040518083038160008887f193505050508015612801575060408051601f3d908101601f191682019092526127fe91810190613e05565b60015b61288b5761280d613c6f565b806308c379a00361283e5750612821613c8b565b8061282c5750612840565b8b81604051602001611c029190613e79565b505b8a604051631101335b60e11b8152600401610629918152604060208201819052601690820152754141323320726576657274656420286f72204f4f472960501b606082015260800190565b95506001600160a01b038216612935576001600160a01b038316600090815260208190526040902080546001600160701b0316808a1115612918578c604051631101335b60e11b81526004016106299181526040602082018190526017908201527f41413231206469646e2774207061792070726566756e64000000000000000000606082015260800190565b81546001600160701b031916908a90036001600160701b03161790555b5a85039650505050505094509492505050565b6001600160a01b038216600090815260016020908152604080832084821c80855292528220805484916001600160401b03831691908561298783613680565b909155501495945050505050565b825160608181015190916000918481116129f15760405162461bcd60e51b815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152606401610629565b60a08201516001600160a01b038116600090815260208190526040902080548784039291906001600160701b031689811015612a79578c604051631101335b60e11b8152600401610629918152604060208201819052601e908201527f41413331207061796d6173746572206465706f73697420746f6f206c6f770000606082015260800190565b8981038260000160006101000a8154816001600160701b0302191690836001600160701b03160217905550826001600160a01b031663f465c77e858e8e602001518e6040518563ffffffff1660e01b8152600401612ad993929190613e54565b60006040518083038160008887f193505050508015612b1a57506040513d6000823e601f3d908101601f19168201604052612b179190810190613eb0565b60015b612ba457612b26613c6f565b806308c379a003612b575750612b3a613c8b565b80612b455750612b59565b8d81604051602001611c029190613f3b565b505b8c604051631101335b60e11b8152600401610629918152604060208201819052601690820152754141333320726576657274656420286f72204f4f472960501b606082015260800190565b909e909d509b505050505050505050505050565b60008082600003612bce57506000928392509050565b6000612bd984612cde565b9050806040015165ffffffffffff16421180612c005750806020015165ffffffffffff1642105b905194909350915050565b6060813560208301356000612c2b612c2660408701876137ab565b613028565b90506000612c3f612c2660608801886137ab565b9050608086013560a087013560c088013560e08901356101008a01356000612c6e612c266101208e018e6137ab565b604080516001600160a01b039c909c1660208d01528b81019a909a5260608b019890985250608089019590955260a088019390935260c087019190915260e08601526101008501526101208401526101408084019190915281518084039091018152610160909201905292915050565b60408051606081018252600080825260208201819052918101919091528160a081901c65ffffffffffff8116600003612d1a575065ffffffffffff5b604080516060810182526001600160a01b03909316835260d09490941c602083015265ffffffffffff16928101929092525090565b6000818310612d5e5781612d60565b825b9392505050565b8015610cf6578251516001600160a01b0381163b15612dd25784604051631101335b60e11b8152600401610629918152604060208201819052601f908201527f414131302073656e64657220616c726561647920636f6e737472756374656400606082015260800190565b835160600151604051632b870d1b60e11b81526000916001600160a01b037f000000000000000000000000dc319bc5b872fc39390546c1b6f68bc574bb4a5e169163570e1a369190612e2a9088908890600401613a32565b60206040518083038160008887f1158015612e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612e6e9190613a46565b90506001600160a01b038116612ed05785604051631101335b60e11b8152600401610629918152604060208201819052601b908201527f4141313320696e6974436f6465206661696c6564206f72204f4f470000000000606082015260800190565b816001600160a01b0316816001600160a01b031614612f3a5785604051631101335b60e11b815260040161062991815260406020808301829052908201527f4141313420696e6974436f6465206d7573742072657475726e2073656e646572606082015260800190565b806001600160a01b03163b600003612f9d5785604051631101335b60e11b815260040161062991815260406020808301829052908201527f4141313520696e6974436f6465206d757374206372656174652073656e646572606082015260800190565b6000612fac60148286886139d3565b612fb5916139fd565b60601c9050826001600160a01b031686602001517fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d83896000015160a001516040516130179291906001600160a01b0392831681529116602082015260400190565b60405180910390a350505050505050565b6000604051828085833790209392505050565b6040518060a001604052806130a060405180610100016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160008152602001600081525090565b8152602001600080191681526020016000815260200160008152602001600081525090565b6000602082840312156130d757600080fd5b813563ffffffff81168114612d6057600080fd5b80356001600160c01b038116811461310257600080fd5b919050565b60006020828403121561311957600080fd5b612d60826130eb565b6001600160a01b038116811461247c57600080fd5b803561310281613122565b6000806040838503121561315557600080fd5b823561316081613122565b915061316e602084016130eb565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b60a081018181106001600160401b03821117156131ac576131ac613177565b60405250565b61010081018181106001600160401b03821117156131ac576131ac613177565b601f8201601f191681016001600160401b03811182821017156131f7576131f7613177565b6040525050565b60006001600160401b0382111561321757613217613177565b50601f01601f191660200190565b600081830361018081121561323957600080fd5b6040516132458161318d565b8092506101008083121561325857600080fd5b6040519250613266836131b2565b61326f85613137565b8352602085013560208401526040850135604084015260608501356060840152608085013560808401526132a560a08601613137565b60a084015260c085013560c084015260e085013560e084015282825280850135602083015250610120840135604082015261014084013560608201526101608401356080820152505092915050565b60008083601f84011261330657600080fd5b5081356001600160401b0381111561331d57600080fd5b60208301915083602082850101111561333557600080fd5b9250929050565b6000806000806101c0858703121561335357600080fd5b84356001600160401b038082111561336a57600080fd5b818701915087601f83011261337e57600080fd5b8135613389816131fe565b60405161339682826131d2565b8281528a60208487010111156133ab57600080fd5b826020860160208301376000602084830101528098505050506133d18860208901613225565b94506101a08701359150808211156133e857600080fd5b506133f5878288016132f4565b95989497509550505050565b60008083601f84011261341357600080fd5b5081356001600160401b0381111561342a57600080fd5b6020830191508360208260051b850101111561333557600080fd5b60008060006040848603121561345a57600080fd5b83356001600160401b0381111561347057600080fd5b61347c86828701613401565b909450925050602084013561349081613122565b809150509250925092565b600080604083850312156134ae57600080fd5b82356134b981613122565b946020939093013593505050565b6000602082840312156134d957600080fd5b8135612d6081613122565b6000806000806000606086880312156134fc57600080fd5b85356001600160401b038082111561351357600080fd5b61351f89838a016132f4565b90975095506020880135915061353482613122565b9093506040870135908082111561354a57600080fd5b50613557888289016132f4565b969995985093965092949392505050565b6000806020838503121561357b57600080fd5b82356001600160401b0381111561359157600080fd5b61359d858286016132f4565b90969095509350505050565b600061016082840312156135bc57600080fd5b50919050565b6000602082840312156135d457600080fd5b81356001600160401b038111156135ea57600080fd5b6125c2848285016135a9565b6000806000806060858703121561360c57600080fd5b84356001600160401b038082111561362357600080fd5b61362f888389016135a9565b95506020870135915061364182613122565b909350604086013590808211156133e857600080fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610d3c57610d3c613657565b60006001820161369257613692613657565b5060010190565b60005b838110156136b457818101518382015260200161369c565b50506000910152565b600081518084526136d5816020860160208601613699565b601f01601f19169290920160200192915050565b8281526040602082015260006125c260408301846136bd565b634e487b7160e01b600052603260045260246000fd5b6000823561015e1983360301811261372f57600080fd5b9190910192915050565b81810381811115610d3c57610d3c613657565b60008235605e1983360301811261372f57600080fd5b6000808335601e1984360301811261377957600080fd5b8301803591506001600160401b0382111561379357600080fd5b6020019150600581901b360382131561333557600080fd5b6000808335601e198436030181126137c257600080fd5b8301803591506001600160401b038211156137dc57600080fd5b60200191503681900382131561333557600080fd5b6000808335601e1984360301811261380857600080fd5b83016020810192503590506001600160401b0381111561382757600080fd5b80360382131561333557600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b600061016061387e8461387185613137565b6001600160a01b03169052565b6020830135602085015261389560408401846137f1565b8260408701526138a88387018284613836565b925050506138b960608401846137f1565b85830360608701526138cc838284613836565b925050506080830135608085015260a083013560a085015260c083013560c085015260e083013560e0850152610100808401358186015250610120613913818501856137f1565b86840383880152613925848284613836565b9350505050610140613939818501856137f1565b8684038388015261394b848284613836565b979650505050505050565b6040808252810184905260006060600586901b830181019083018783805b898110156139bc57868503605f190184528235368c900361015e1901811261399a578283fd5b6139a6868d830161385f565b9550506020938401939290920191600101613974565b50505050828103602084015261394b818587613836565b600080858511156139e357600080fd5b838611156139f057600080fd5b5050820193919092039150565b6bffffffffffffffffffffffff198135818116916014851015613a2a5780818660140360031b1b83161692505b505092915050565b6020815260006125c2602083018486613836565b600060208284031215613a5857600080fd5b8151612d6081613122565b65ffffffffffff818116838216019080821115613a8257613a82613657565b5092915050565b8183823760009101908152919050565b868152856020820152600065ffffffffffff8087166040840152808616606084015250831515608083015260c060a0830152613ad860c08301846136bd565b98975050505050505050565b80518252602081015160208301526040810151151560408301526000606082015165ffffffffffff8082166060860152806080850151166080860152505060a082015160c060a08501526125c260c08501826136bd565b6000610140808352613b4f81840189613ae4565b915050613b69602083018780518252602090810151910152565b845160608301526020948501516080830152835160a08301529284015160c082015281516001600160a01b031660e0820152908301518051610100830152909201516101209092019190915292915050565b60e081526000613bce60e0830187613ae4565b9050613be7602083018680518252602090810151910152565b8351606083015260208401516080830152825160a0830152602083015160c083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b600060038510613c4857634e487b7160e01b600052602160045260246000fd5b84825260606020830152613c5f60608301856136bd565b9050826040830152949350505050565b600060033d1115613c885760046000803e5060005160e01c5b90565b600060443d1015613c995790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715613cc857505050505090565b8285019150815181811115613ce05750505050505090565b843d8701016020828501011115613cfa5750505050505090565b613d09602082860101876131d2565b509095945050505050565b75020a09a98103837b9ba27b8103932bb32b93a32b21d160551b815260008251613d45816016850160208701613699565b9190910160160192915050565b60006101c0808352613d678184018789613836565b9050845160018060a01b03808251166020860152602082015160408601526040820151606086015260608201516080860152608082015160a08601528060a08301511660c08601525060c081015160e085015260e08101516101008501525060208501516101208401526040850151610140840152606085015161016084015260808501516101808401528281036101a084015261394b81856136bd565b600060208284031215613e1757600080fd5b5051919050565b606081526000613e32606083018789613836565b6001600160a01b03861660208401528281036040840152613ad8818587613836565b606081526000613e67606083018661385f565b60208301949094525060400152919050565b6e020a09919903932bb32b93a32b21d1608d1b815260008251613ea381600f850160208701613699565b91909101600f0192915050565b60008060408385031215613ec357600080fd5b82516001600160401b03811115613ed957600080fd5b8301601f81018513613eea57600080fd5b8051613ef5816131fe565b604051613f0282826131d2565b828152876020848601011115613f1757600080fd5b613f28836020830160208701613699565b6020969096015195979596505050505050565b6e020a09999903932bb32b93a32b21d1608d1b815260008251613ea381600f85016020870161369956fea2646970667358221220bc5c14ed3ec926af1ab28e2fd999437beb980f78c0fe5ff3c1e6bd7d67fe265c64736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
TAIKO | 100.00% | $1,811.48 | 0.9199 | $1,666.29 |
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.