MATIC Price: $0.72013 (-1.08%)
Gas: 35 GWei
 

Overview

MATIC Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 MATIC

MATIC Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value

There are no matching entries

Please try again later

Latest 1 internal transaction

Parent Transaction Hash Block From To Value
323965452022-08-28 1:14:39641 days ago1661649279  Contract Creation0 MATIC
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
EntryPoint

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 12 : EntryPoint.sol
/**
 ** 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 'hardhat/console.sol';
import '../interfaces/IWallet.sol';
import '../interfaces/IPaymaster.sol';

import '../interfaces/IAggregatedWallet.sol';
import '../interfaces/IEntryPoint.sol';
import '../interfaces/ICreate2Deployer.sol';
import '../utils/Exec.sol';
import './StakeManager.sol';

contract EntryPoint is IEntryPoint, StakeManager {
    using UserOperationLib for UserOperation;

    // internal value used during simulation: need to query aggregator if wallet is created
    address private constant SIMULATE_NO_AGGREGATOR = address(1);

    /**
     * @param _paymasterStake - minimum required locked stake for a paymaster
     * @param _unstakeDelaySec - minimum time (in seconds) a paymaster stake must be locked
     */
    constructor(uint256 _paymasterStake, uint32 _unstakeDelaySec)
        StakeManager(_paymasterStake, _unstakeDelaySec)
    {
        require(_unstakeDelaySec > 0, 'invalid unstakeDelay');
        require(_paymasterStake > 0, 'invalid paymasterStake');
    }

    /**
     * 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), 'invalid beneficiary');
        (bool success, ) = beneficiary.call{value: amount}('');
        require(success);
    }

    /**
     * execute a user op
     * @param opIndex into into the opInfo array
     * @param userOp the userOp to execute
     * @param opInfo the opInfo filled by validatePrepayment for this userOp.
     * @return collected the total amount this userOp paid.
     */
    function _executeUserOp(
        uint256 opIndex,
        UserOperation calldata userOp,
        UserOpInfo memory opInfo
    ) private returns (uint256 collected) {
        uint256 preGas = gasleft();
        console.log(preGas);
        bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);

        try this.innerHandleOp(userOp.callData, opInfo, context) returns (
            uint256 _actualGasCost
        ) {
            collected = _actualGasCost;
        } catch {
            uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;
            collected = _handlePostOp(
                opIndex,
                IPaymaster.PostOpMode.postOpReverted,
                opInfo,
                context,
                actualGas
            );
        }
    }

    /**
     * Execute a batch of UserOperation.
     * no signature aggregator is used.
     * if any wallet requires an aggregator (that is, it returned an "actualAggregator" when
     * performing simulateValidation), then handleAggregatedOps() must be used instead.
     * @param ops the operations to execute
     * @param beneficiary the address to receive the fees
     */
    function handleOps(
        UserOperation[] calldata ops,
        address payable beneficiary
    ) public {
        uint256 opslen = ops.length;
        UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);

        unchecked {
            for (uint256 i = 0; i < opslen; i++) {
                _validatePrepayment(i, ops[i], opInfos[i], address(0));
            }

            console.log('caloidation completed?');

            uint256 collected = 0;

            for (uint256 i = 0; i < opslen; i++) {
                console.log('first operation');
                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 wallets)
     * @param beneficiary the address to receive the fees
     */
    function handleAggregatedOps(
        UserOpsPerAggregator[] calldata opsPerAggregator,
        address payable beneficiary
    ) public {
        uint256 opasLen = opsPerAggregator.length;
        uint256 totalOps = 0;
        for (uint256 i = 0; i < opasLen; i++) {
            totalOps += opsPerAggregator[i].userOps.length;
        }

        UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);

        uint256 opIndex = 0;
        for (uint256 a = 0; a < opasLen; a++) {
            UserOpsPerAggregator calldata opa = opsPerAggregator[a];
            UserOperation[] calldata ops = opa.userOps;
            IAggregator aggregator = opa.aggregator;
            uint256 opslen = ops.length;
            for (uint256 i = 0; i < opslen; i++) {
                _validatePrepayment(
                    opIndex,
                    ops[i],
                    opInfos[opIndex],
                    address(aggregator)
                );
                opIndex++;
            }

            if (address(aggregator) != address(0)) {
                // solhint-disable-next-line no-empty-blocks
                try aggregator.validateSignatures(ops, opa.signature) {} catch {
                    revert SignatureValidationFailed(address(aggregator));
                }
            }
        }

        uint256 collected = 0;
        opIndex = 0;
        for (uint256 a = 0; a < opasLen; a++) {
            UserOpsPerAggregator calldata opa = opsPerAggregator[a];
            UserOperation[] calldata ops = opa.userOps;
            uint256 opslen = ops.length;

            for (uint256 i = 0; i < opslen; i++) {
                collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);
                opIndex++;
            }
        }

        _compensate(beneficiary, collected);
    }

    //a memory copy of UserOp fields (except that dynamic byte arrays: callData, initCode and signature
    struct MemoryUserOp {
        address sender;
        uint256 nonce;
        uint256 callGasLimit;
        uint256 verificationGasLimit;
        uint256 preVerificationGas;
        address paymaster;
        uint256 maxFeePerGas;
        uint256 maxPriorityFeePerGas;
    }

    struct UserOpInfo {
        MemoryUserOp mUserOp;
        bytes32 requestId;
        uint256 prefund;
        uint256 contextOffset;
        uint256 preOpGas;
    }

    /**
     * inner function to handle a UserOperation.
     * Must be declared "external" to open a call context, but it can only be called by handleOps.
     */
    function innerHandleOp(
        bytes calldata callData,
        UserOpInfo memory opInfo,
        bytes calldata context
    ) external returns (uint256 actualGasCost) {
        uint256 preGas = gasleft();
        console.log('inner handleop');
        require(msg.sender == address(this));
        MemoryUserOp memory mUserOp = opInfo.mUserOp;

        IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;
        if (callData.length > 0) {
            console.log('calling the function');
            console.log(address(mUserOp.sender));

            (bool success, bytes memory result) = address(mUserOp.sender).call{
                gas: mUserOp.callGasLimit
            }(callData);
            console.log(success);
            if (!success) {
                if (result.length > 0) {
                    emit UserOperationRevertReason(
                        opInfo.requestId,
                        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 getRequestId(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, 'invalid paymasterAndData');
            mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));
        } else {
            mUserOp.paymaster = address(0);
        }
    }

    /**
     * Simulate a call to wallet.validateUserOp and paymaster.validatePaymasterUserOp.
     * Validation succeeds if the call doesn't revert.
     * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the wallet's data.
     *      In order to split the running opcodes of the wallet (validateUserOp) from the paymaster's validatePaymasterUserOp,
     *      it should look for the NUMBER opcode at depth=1 (which itself is a banned opcode)
     * @param userOp the user operation to validate.
     * @param offChainSigCheck if the wallet has an aggregator, skip on-chain aggregation check. In thus case, the bundler must
     *          perform the equivalent check using an off-chain library code
     * @return preOpGas total gas used by validation (including contract creation)
     * @return prefund the amount the wallet had to prefund (zero in case a paymaster pays)
     * @return actualAggregator the aggregator used by this userOp. if a non-zero aggregator is returned, the bundler must get its params using
     *      aggregator.
     * @return sigForUserOp - only if has actualAggregator: this value is returned from IAggregator.validateUserOpSignature, and should be placed in the userOp.signature when creating a bundle.
     * @return sigForAggregation  - only if has actualAggregator:  this value is returned from IAggregator.validateUserOpSignature, and should be passed to aggregator.aggregateSignatures
     * @return offChainSigInfo - if has actualAggregator, and offChainSigCheck is true, this value should be used by the off-chain signature code (e.g. it contains the sender's publickey)
     */
    function simulateValidation(
        UserOperation calldata userOp,
        bool offChainSigCheck
    )
        external
        returns (
            uint256 preOpGas,
            uint256 prefund,
            address actualAggregator,
            bytes memory sigForUserOp,
            bytes memory sigForAggregation,
            bytes memory offChainSigInfo
        )
    {
        uint256 preGas = gasleft();

        UserOpInfo memory outOpInfo;

        actualAggregator = _validatePrepayment(
            0,
            userOp,
            outOpInfo,
            SIMULATE_NO_AGGREGATOR
        );
        prefund = outOpInfo.prefund;
        preOpGas = preGas - gasleft() + userOp.preVerificationGas;

        numberMarker();
        if (actualAggregator != address(0)) {
            (sigForUserOp, sigForAggregation, offChainSigInfo) = IAggregator(
                actualAggregator
            ).validateUserOpSignature(userOp, offChainSigCheck);
        }
        require(
            msg.sender == address(0),
            'must be called off-chain with from=zero-addr'
        );
    }

    function _getRequiredPrefund(MemoryUserOp memory mUserOp)
        internal
        view
        returns (uint256 requiredPrefund)
    {
        unchecked {
            //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.
            // our security model might call postOp eventually twice
            uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;
            uint256 requiredGas = mUserOp.callGasLimit +
                mUserOp.verificationGasLimit *
                mul +
                mUserOp.preVerificationGas;

            // TODO: copy logic of gasPrice?
            requiredPrefund = requiredGas * getUserOpGasPrice(mUserOp);
        }
    }

    // create the sender's contract if needed.
    function _createSenderIfNeeded(
        MemoryUserOp memory mUserOp,
        bytes calldata initCode
    ) internal {
        if (initCode.length != 0) {
            require(
                mUserOp.sender.code.length == 0,
                'sender already constructed'
            );
            address sender1 = _createSender(initCode);
            require(
                sender1 == mUserOp.sender,
                "sender doesn't match initCode address"
            );
            require(
                sender1.code.length != 0,
                'initCode failed to create sender'
            );
        }
    }

    /**
     * call the "initCode" factory to create and return the sender wallet address
     * initCode must be unique (e.g. contains the signer address), to make sure
     *  it can only be executed from the entryPoint, and called with its initialization code (callData)
     * @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 wallet.
     */
    function _createSender(bytes calldata initCode)
        internal
        returns (address sender)
    {
        address initAddress = address(bytes20(initCode[0:20]));
        bytes memory initCallData = initCode[20:];
        bool success;
        assembly {
            success := call(
                gas(),
                initAddress,
                0,
                add(initCallData, 0x20),
                mload(initCallData),
                0,
                32
            )
            sender := mload(0)
        }
        require(success, 'initCode failed');
    }

    /**
     * helper: make a "view" call to calculate the sender address.
     * must be called from zero-address.
     */
    function getSenderAddress(bytes calldata initCode)
        public
        returns (address sender)
    {
        require(
            msg.sender == address(0),
            'must be called off-chain with from=zero-addr'
        );
        return _createSender(initCode);
    }

    /**
     * call wallet.validateUserOp.
     * revert (with FailedOp) in case validateUserOp reverts, or wallet didn't send required prefund.
     * decrement wallet's deposit if needed
     */
    function _validateWalletPrepayment(
        uint256 opIndex,
        UserOperation calldata op,
        UserOpInfo memory opInfo,
        address aggregator,
        uint256 requiredPrefund
    )
        internal
        returns (
            uint256 gasUsedByValidateWalletPrepayment,
            address actualAggregator
        )
    {
        unchecked {
            uint256 preGas = gasleft();
            MemoryUserOp memory mUserOp = opInfo.mUserOp;
            _createSenderIfNeeded(mUserOp, op.initCode);
            if (aggregator == SIMULATE_NO_AGGREGATOR) {
                try IAggregatedWallet(mUserOp.sender).getAggregator() returns (
                    address userOpAggregator
                ) {
                    aggregator = actualAggregator = userOpAggregator;
                } catch {
                    aggregator = actualAggregator = address(0);
                }
            }
            uint256 missingWalletFunds = 0;
            address sender = mUserOp.sender;
            address paymaster = mUserOp.paymaster;
            if (paymaster == address(0)) {
                uint256 bal = balanceOf(sender);
                missingWalletFunds = bal > requiredPrefund
                    ? 0
                    : requiredPrefund - bal;
            }
            // solhint-disable-next-line no-empty-blocks
            try
                IWallet(sender).validateUserOp{
                    gas: mUserOp.verificationGasLimit
                }(op, opInfo.requestId, aggregator, missingWalletFunds)
            {} catch Error(string memory revertReason) {
                revert FailedOp(opIndex, address(0), revertReason);
            } catch {
                revert FailedOp(opIndex, address(0), '');
            }
            if (paymaster == address(0)) {
                DepositInfo storage senderInfo = deposits[sender];
                uint256 deposit = senderInfo.deposit;
                if (requiredPrefund > deposit) {
                    revert FailedOp(
                        opIndex,
                        address(0),
                        "wallet didn't pay prefund"
                    );
                }
                senderInfo.deposit = uint112(deposit - requiredPrefund);
            }
            gasUsedByValidateWalletPrepayment = preGas - gasleft();
        }
    }

    /**
     * in case the request has a paymaster:
     * validate paymaster is staked and has enough deposit.
     * call paymaster.validatePaymasterUserOp.
     * revert with proper FailedOp in case paymaster reverts.
     * decrement paymaster's deposit
     */
    function _validatePaymasterPrepayment(
        uint256 opIndex,
        UserOperation calldata op,
        UserOpInfo memory opInfo,
        uint256 requiredPreFund,
        uint256 gasUsedByValidateWalletPrepayment
    ) internal returns (bytes memory context) {
        unchecked {
            MemoryUserOp memory mUserOp = opInfo.mUserOp;
            address paymaster = mUserOp.paymaster;
            DepositInfo storage paymasterInfo = deposits[paymaster];
            uint256 deposit = paymasterInfo.deposit;
            bool staked = paymasterInfo.staked;
            if (!staked) {
                revert FailedOp(opIndex, paymaster, 'not staked');
            }
            if (deposit < requiredPreFund) {
                revert FailedOp(
                    opIndex,
                    paymaster,
                    'paymaster deposit too low'
                );
            }
            paymasterInfo.deposit = uint112(deposit - requiredPreFund);
            uint256 gas = mUserOp.verificationGasLimit -
                gasUsedByValidateWalletPrepayment;
            try
                IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(
                    op,
                    opInfo.requestId,
                    requiredPreFund
                )
            returns (bytes memory _context) {
                context = _context;
            } catch Error(string memory revertReason) {
                revert FailedOp(opIndex, paymaster, revertReason);
            } catch {
                revert FailedOp(opIndex, paymaster, '');
            }
        }
    }

    /**
     * validate wallet and paymaster (if defined).
     * also make sure total validation doesn't exceed verificationGasLimit
     * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)
     * @param opIndex the index of this userOp into the "opInfos" array
     * @param userOp the userOp to validate
     */
    function _validatePrepayment(
        uint256 opIndex,
        UserOperation calldata userOp,
        UserOpInfo memory outOpInfo,
        address aggregator
    ) private returns (address actualAggregator) {
        uint256 preGas = gasleft();
        MemoryUserOp memory mUserOp = outOpInfo.mUserOp;
        _copyUserOpToMemory(userOp, mUserOp);
        outOpInfo.requestId = getRequestId(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, 'gas values overflow');

        uint256 gasUsedByValidateWalletPrepayment;
        uint256 requiredPreFund = _getRequiredPrefund(mUserOp);
        (
            gasUsedByValidateWalletPrepayment,
            actualAggregator
        ) = _validateWalletPrepayment(
            opIndex,
            userOp,
            outOpInfo,
            aggregator,
            requiredPreFund
        );

        //a "marker" where wallet 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 = _validatePaymasterPrepayment(
                opIndex,
                userOp,
                outOpInfo,
                requiredPreFund,
                gasUsedByValidateWalletPrepayment
            );
        } else {
            context = '';
        }
        unchecked {
            uint256 gasUsed = preGas - gasleft();

            if (userOp.verificationGasLimit < gasUsed) {
                revert FailedOp(
                    opIndex,
                    mUserOp.paymaster,
                    'Used more than 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 wallet (or paymaster - if it is was used in the request)
     * @param opIndex index in the batch
     * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)
     * @param opInfo userOp fields and info collected during validation
     * @param context the context returned in validatePaymasterUserOp
     * @param actualGas the gas used so far by this user operation
     */
    function _handlePostOp(
        uint256 opIndex,
        IPaymaster.PostOpMode mode,
        UserOpInfo memory opInfo,
        bytes memory context,
        uint256 actualGas
    ) private returns (uint256 actualGasCost) {
        uint256 preGas = gasleft();
        unchecked {
            address refundAddress;
            MemoryUserOp memory mUserOp = opInfo.mUserOp;
            uint256 gasPrice = getUserOpGasPrice(mUserOp);

            address paymaster = mUserOp.paymaster;
            if (paymaster == address(0)) {
                refundAddress = mUserOp.sender;
            } else {
                refundAddress = paymaster;
                if (context.length > 0) {
                    actualGasCost = actualGas * gasPrice;
                    if (mode != IPaymaster.PostOpMode.postOpReverted) {
                        IPaymaster(paymaster).postOp{
                            gas: mUserOp.verificationGasLimit
                        }(mode, context, actualGasCost);
                    } else {
                        // solhint-disable-next-line no-empty-blocks
                        try
                            IPaymaster(paymaster).postOp{
                                gas: mUserOp.verificationGasLimit
                            }(mode, context, actualGasCost)
                        {} catch Error(string memory reason) {
                            revert FailedOp(opIndex, paymaster, reason);
                        } catch {
                            revert FailedOp(
                                opIndex,
                                paymaster,
                                'postOp revert'
                            );
                        }
                    }
                }
            }
            actualGas += preGas - gasleft();
            actualGasCost = actualGas * gasPrice;
            if (opInfo.prefund < actualGasCost) {
                revert FailedOp(
                    opIndex,
                    paymaster,
                    'prefund below actualGasCost'
                );
            }
            uint256 refund = opInfo.prefund - actualGasCost;
            internalIncrementDeposit(refundAddress, refund);
            bool success = mode == IPaymaster.PostOpMode.opSucceeded;
            emit UserOperationEvent(
                opInfo.requestId,
                mUserOp.sender,
                mUserOp.paymaster,
                mUserOp.nonce,
                actualGasCost,
                gasPrice,
                success
            );
        } // unchecked
    }

    /**
     * return the storage cells used internally by the EntryPoint for this sender address.
     * During `simulateValidation`, allow these storage cells to be accessed
     *  (that is, a wallet/paymaster are allowed to access their own deposit balance on the
     *  EntryPoint's storage, but no other account)
     */
    function getSenderStorage(address sender)
        external
        view
        returns (uint256[] memory senderStorageCells)
    {
        uint256 cell;
        DepositInfo storage info = deposits[sender];

        assembly {
            cell := info.slot
        }
        senderStorageCells = new uint256[](1);
        senderStorageCells[0] = cell;
    }

    /**
     * the gas price this UserOp agrees to pay.
     * relayer/miner 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
    // wallet and paymaster.
    function numberMarker() internal view {
        assembly {
            mstore(0, number())
        }
    }
}

File 2 of 12 : console.sol
// SPDX-License-Identifier: MIT
pragma solidity >= 0.4.22 <0.9.0;

library console {
	address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);

	function _sendLogPayload(bytes memory payload) private view {
		uint256 payloadLength = payload.length;
		address consoleAddress = CONSOLE_ADDRESS;
		assembly {
			let payloadStart := add(payload, 32)
			let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
		}
	}

	function log() internal view {
		_sendLogPayload(abi.encodeWithSignature("log()"));
	}

	function logInt(int256 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
	}

	function logUint(uint256 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
	}

	function logString(string memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
	}

	function logBool(bool p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
	}

	function logAddress(address p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
	}

	function logBytes(bytes memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
	}

	function logBytes1(bytes1 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
	}

	function logBytes2(bytes2 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
	}

	function logBytes3(bytes3 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
	}

	function logBytes4(bytes4 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
	}

	function logBytes5(bytes5 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
	}

	function logBytes6(bytes6 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
	}

	function logBytes7(bytes7 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
	}

	function logBytes8(bytes8 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
	}

	function logBytes9(bytes9 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
	}

	function logBytes10(bytes10 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
	}

	function logBytes11(bytes11 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
	}

	function logBytes12(bytes12 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
	}

	function logBytes13(bytes13 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
	}

	function logBytes14(bytes14 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
	}

	function logBytes15(bytes15 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
	}

	function logBytes16(bytes16 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
	}

	function logBytes17(bytes17 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
	}

	function logBytes18(bytes18 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
	}

	function logBytes19(bytes19 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
	}

	function logBytes20(bytes20 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
	}

	function logBytes21(bytes21 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
	}

	function logBytes22(bytes22 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
	}

	function logBytes23(bytes23 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
	}

	function logBytes24(bytes24 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
	}

	function logBytes25(bytes25 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
	}

	function logBytes26(bytes26 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
	}

	function logBytes27(bytes27 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
	}

	function logBytes28(bytes28 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
	}

	function logBytes29(bytes29 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
	}

	function logBytes30(bytes30 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
	}

	function logBytes31(bytes31 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
	}

	function logBytes32(bytes32 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
	}

	function log(uint256 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
	}

	function log(string memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
	}

	function log(bool p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
	}

	function log(address p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
	}

	function log(uint256 p0, uint256 p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
	}

	function log(uint256 p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
	}

	function log(uint256 p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
	}

	function log(uint256 p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
	}

	function log(string memory p0, uint256 p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
	}

	function log(string memory p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
	}

	function log(string memory p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
	}

	function log(string memory p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
	}

	function log(bool p0, uint256 p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
	}

	function log(bool p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
	}

	function log(bool p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
	}

	function log(bool p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
	}

	function log(address p0, uint256 p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
	}

	function log(address p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
	}

	function log(address p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
	}

	function log(address p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
	}

	function log(uint256 p0, uint256 p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
	}

	function log(uint256 p0, uint256 p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
	}

	function log(uint256 p0, uint256 p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
	}

	function log(uint256 p0, uint256 p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
	}

	function log(uint256 p0, string memory p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
	}

	function log(uint256 p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
	}

	function log(uint256 p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
	}

	function log(uint256 p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
	}

	function log(uint256 p0, bool p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
	}

	function log(uint256 p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
	}

	function log(uint256 p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
	}

	function log(uint256 p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
	}

	function log(uint256 p0, address p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
	}

	function log(uint256 p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
	}

	function log(uint256 p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
	}

	function log(uint256 p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
	}

	function log(string memory p0, uint256 p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
	}

	function log(string memory p0, uint256 p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
	}

	function log(string memory p0, uint256 p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
	}

	function log(string memory p0, uint256 p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
	}

	function log(string memory p0, address p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
	}

	function log(string memory p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
	}

	function log(string memory p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
	}

	function log(string memory p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
	}

	function log(bool p0, uint256 p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
	}

	function log(bool p0, uint256 p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
	}

	function log(bool p0, uint256 p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
	}

	function log(bool p0, uint256 p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
	}

	function log(bool p0, bool p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
	}

	function log(bool p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
	}

	function log(bool p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
	}

	function log(bool p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
	}

	function log(bool p0, address p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
	}

	function log(bool p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
	}

	function log(bool p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
	}

	function log(bool p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
	}

	function log(address p0, uint256 p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
	}

	function log(address p0, uint256 p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
	}

	function log(address p0, uint256 p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
	}

	function log(address p0, uint256 p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
	}

	function log(address p0, string memory p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
	}

	function log(address p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
	}

	function log(address p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
	}

	function log(address p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
	}

	function log(address p0, bool p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
	}

	function log(address p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
	}

	function log(address p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
	}

	function log(address p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
	}

	function log(address p0, address p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
	}

	function log(address p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
	}

	function log(address p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
	}

	function log(address p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
	}

	function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
	}

}

File 2 of 12 : IWallet.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.12;

import "./UserOperation.sol";

interface IWallet {

    /**
     * Validate user's signature and nonce
     * the entryPoint will make the call to the recipient only if this validation call returns successfully.
     *
     * @dev Must validate caller is the entryPoint.
     *      Must validate the signature and nonce
     * @param userOp the operation that is about to be executed.
     * @param requestId hash of the user's request data. can be used as the basis for signature.
     * @param aggregator the aggregator used to validate the signature. NULL for non-aggregated signature wallets.
     * @param missingWalletFunds missing funds on the wallet'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.
     */
    function validateUserOp(UserOperation calldata userOp, bytes32 requestId, address aggregator, uint256 missingWalletFunds) external;
}

File 2 of 12 : IPaymaster.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.12;

import "./UserOperation.sol";

/**
 * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.
 * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.
 */
interface IPaymaster {

    /**
     * payment validation: check if paymaster agree to pay.
     * Must verify sender is the entryPoint.
     * Revert to reject this request.
     * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)
     * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.
     * @param userOp the user operation
     * @param requestId 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.
     */
    function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 requestId, uint256 maxCost) external returns (bytes memory context);

    /**
     * post-operation handler.
     * Must verify sender is the entryPoint
     * @param mode enum with the following options:
     *      opSucceeded - user operation succeeded.
     *      opReverted  - user op reverted. still has to pay for gas.
     *      postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.
     *                       Now this is the 2nd call, after user's op was deliberately reverted.
     * @param context - the context value returned by validatePaymasterUserOp
     * @param actualGasCost - actual gas used so far (without this postOp call).
     */
    function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;

    enum PostOpMode {
        opSucceeded, // user op succeeded
        opReverted, // user op reverted. still has to pay for gas.
        postOpReverted //user op succeeded, but caused postOp to revert. Now its a 2nd call, after user's op was deliberately reverted.
    }
}

File 2 of 12 : IAggregatedWallet.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.12;

import "./UserOperation.sol";
import "./IWallet.sol";
import "./IAggregator.sol";

/**
 * Aggregated wallet, that support IAggregator.
 * - the validateUserOp will be called only after the aggregator validated this wallet (with all other wallets of this aggregator).
 * - the validateUserOp MUST valiate the aggregator parameter, and MAY ignore the userOp.signature field.
 */
interface IAggregatedWallet is IWallet {

    /**
     * return the address of the signature aggregator the wallet supports.
     */
    function getAggregator() external view returns (address);
}

File 2 of 12 : IEntryPoint.sol
/**
 ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.
 ** Only one instance required on each chain.
 **/
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.12;

/* solhint-disable avoid-low-level-calls */
/* solhint-disable no-inline-assembly */
/* solhint-disable reason-string */

import "./UserOperation.sol";
import "./IStakeManager.sol";
import "./IAggregator.sol";

interface IEntryPoint is IStakeManager {

    /***
     * An event emitted after each successful request
     * @param requestId - unique identifier for the request (hash its entire content, except signature).
     * @param sender - the account that generates this request.
     * @param paymaster - if non-null, the paymaster that pays for this request.
     * @param nonce - the nonce value from the request
     * @param actualGasCost - the total cost (in gas) of this request.
     * @param actualGasPrice - the actual gas price the sender agreed to pay.
     * @param success - true if the sender transaction succeeded, false if reverted.
     */
    event UserOperationEvent(bytes32 indexed requestId, address indexed sender, address indexed paymaster, uint256 nonce, uint256 actualGasCost, uint256 actualGasPrice, bool success);

    /**
     * An event emitted if the UserOperation "callData" reverted with non-zero length
     * @param requestId 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 requestId, address indexed sender, uint256 nonce, bytes revertReason);

    /**
     * a custom revert error of handleOps, to identify the offending op.
     *  NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.
     *  @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)
     *  @param paymaster - if paymaster.validatePaymasterUserOp fails, this will be the paymaster's address. if validateUserOp failed,
     *       this value will be zero (since it failed before accessing the paymaster)
     *  @param reason - revert reason
     *   Should be caught in off-chain handleOps simulation and not happen on-chain.
     *   Useful for mitigating DoS attempts against batchers or for troubleshooting of wallet/paymaster reverts.
     */
    error FailedOp(uint256 opIndex, address paymaster, string reason);

    /**
     * error case when a signature aggregator fails to verify the aggregated signature it had created.
     */
    error SignatureValidationFailed(address aggregator);

    //UserOps handled, per aggregator
    struct UserOpsPerAggregator {
        UserOperation[] userOps;

        // aggregator address
        IAggregator aggregator;
        // aggregated signature
        bytes signature;
    }

    /**
     * Execute a batch of UserOperation.
     * no signature aggregator is used.
     * if any wallet requires an aggregator (that is, it returned an "actualAggregator" when
     * performing simulateValidation), then handleAggregatedOps() must be used instead.
     * @param ops the operations to execute
     * @param beneficiary the address to receive the fees
     */
    function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;

    /**
     * Execute a batch of UserOperation with Aggregators
     * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator wallets)
     * @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 getRequestId(UserOperation calldata userOp) external view returns (bytes32);

    /**
    * Simulate a call to wallet.validateUserOp and paymaster.validatePaymasterUserOp.
    * Validation succeeds if the call doesn't revert.
    * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the wallet's data.
     *      In order to split the running opcodes of the wallet (validateUserOp) from the paymaster's validatePaymasterUserOp,
     *      it should look for the NUMBER opcode at depth=1 (which itself is a banned opcode)
     * @param userOp the user operation to validate.
     * @param offChainSigCheck if the wallet has an aggregator, skip on-chain aggregation check. In thus case, the bundler must
     *          perform the equivalent check using an off-chain library code
     * @return preOpGas total gas used by validation (including contract creation)
     * @return prefund the amount the wallet had to prefund (zero in case a paymaster pays)
     * @return actualAggregator the aggregator used by this userOp. if a non-zero aggregator is returned, the bundler must get its params using
     *      aggregator.
     * @return sigForUserOp - only if has actualAggregator: this value is returned from IAggregator.validateUserOpSignature, and should be placed in the userOp.signature when creating a bundle.
     * @return sigForAggregation  - only if has actualAggregator:  this value is returned from IAggregator.validateUserOpSignature, and should be passed to aggregator.aggregateSignatures
     * @return offChainSigInfo - if has actualAggregator, and offChainSigCheck is true, this value should be used by the off-chain signature code (e.g. it contains the sender's publickey)
     */
    function simulateValidation(UserOperation calldata userOp, bool offChainSigCheck)
    external returns (uint256 preOpGas, uint256 prefund, address actualAggregator, bytes memory sigForUserOp, bytes memory sigForAggregation, bytes memory offChainSigInfo);

    /**
     * Get counterfactual sender address.
     *  Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.
     * must be called from zero-address.
     * @param initCode the constructor code to be passed into the UserOperation.
     */
    function getSenderAddress(bytes memory initCode) external returns (address);

    /**
     * return the storage cells used internally by the EntryPoint for this sender address.
     * During `simulateValidation`, allow these storage cells to be accessed
     *  (that is, a wallet/paymaster are allowed to access their own deposit balance on the
     *  EntryPoint's storage, but no other account)
     */
    function getSenderStorage(address sender) external view returns (uint256[] memory senderStorageCells);
}

File 2 of 12 : ICreate2Deployer.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.12;

/**
 * create2-based deployer (eip-2470)
 */
interface ICreate2Deployer {
    function deploy(bytes memory initCode, bytes32 salt) external returns (address);
}

File 2 of 12 : Exec.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.5 <0.9.0;

// solhint-disable no-inline-assembly

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() internal pure returns (bytes memory returnData) {
        assembly {
            let ptr := mload(0x40)
            mstore(0x40, add(ptr, add(returndatasize(), 0x20)))
            mstore(ptr, returndatasize())
            returndatacopy(add(ptr, 0x20), 0, returndatasize())
            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) internal {
        bool success = call(to,0,data,gasleft());
        if (!success) {
            revertWithData(getReturnData());
        }
    }
}

File 2 of 12 : StakeManager.sol
// 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 a wallet)
 * stake is value locked for at least "unstakeDelay" by a paymaster.
 */
abstract contract StakeManager is IStakeManager {

    /**
     * minimum time (in seconds) required to lock a paymaster stake before it can be withdraw.
     */
    uint32 immutable public unstakeDelaySec;

    /**
     * minimum value required to stake for a paymaster
     */
    uint256 immutable public paymasterStake;

    constructor(uint256 _paymasterStake, uint32 _unstakeDelaySec) {
        unstakeDelaySec = _unstakeDelaySec;
        paymasterStake = _paymasterStake;
    }

    /// maps paymaster to their deposits and stakes
    mapping(address => DepositInfo) public deposits;

    function getDepositInfo(address account) public view returns (DepositInfo memory info) {
        return deposits[account];
    }

    /// return the deposit (for gas payment) of the account
    function balanceOf(address account) public view returns (uint256) {
        return deposits[account].deposit;
    }

    receive() external payable {
        depositTo(msg.sender);
    }

    function internalIncrementDeposit(address account, uint256 amount) internal {
        DepositInfo storage info = deposits[account];
        uint256 newAmount = info.deposit + amount;
        require(newAmount <= type(uint112).max, "deposit overflow");
        info.deposit = uint112(newAmount);
    }

    /**
     * add to the deposit of the given account
     */
    function depositTo(address account) public payable {
        internalIncrementDeposit(account, msg.value);
        DepositInfo storage info = deposits[account];
        emit Deposited(account, info.deposit);
    }

    /**
     * add to the account's stake - amount and delay
     * any pending unstake is first cancelled.
     * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.
     */
    function addStake(uint32 _unstakeDelaySec) public payable {
        DepositInfo storage info = deposits[msg.sender];
        require(_unstakeDelaySec >= unstakeDelaySec, "unstake delay too low");
        require(_unstakeDelaySec >= info.unstakeDelaySec, "cannot decrease unstake time");
        uint256 stake = info.stake + msg.value;
        require(stake >= paymasterStake, "stake value too low");
        require(stake < type(uint112).max, "stake overflow");
        deposits[msg.sender] = DepositInfo(
            info.deposit,
            true,
            uint112(stake),
            _unstakeDelaySec,
            0
        );
        emit StakeLocked(msg.sender, stake, _unstakeDelaySec);
    }

    /**
     * attempt to unlock the stake.
     * the value can be withdrawn (using withdrawStake) after the unstake delay.
     */
    function unlockStake() external {
        DepositInfo storage info = deposits[msg.sender];
        require(info.unstakeDelaySec != 0, "not staked");
        require(info.staked, "already unstaking");
        uint64 withdrawTime = uint64(block.timestamp) + info.unstakeDelaySec;
        info.withdrawTime = withdrawTime;
        info.staked = false;
        emit StakeUnlocked(msg.sender, withdrawTime);
    }


    /**
     * withdraw from the (unlocked) stake.
     * must first call unlockStake and wait for the unstakeDelay to pass
     * @param withdrawAddress the address to send withdrawn value.
     */
    function withdrawStake(address payable withdrawAddress) external {
        DepositInfo storage info = deposits[msg.sender];
        uint256 stake = info.stake;
        require(stake > 0, "No stake to withdraw");
        require(info.withdrawTime > 0, "must call unlockStake() first");
        require(info.withdrawTime <= block.timestamp, "Stake withdrawal is not due");
        info.unstakeDelaySec = 0;
        info.withdrawTime = 0;
        info.stake = 0;
        emit StakeWithdrawn(msg.sender, withdrawAddress, stake);
        (bool success,) = withdrawAddress.call{value : stake}("");
        require(success, "failed to withdraw stake");
    }

    /**
     * withdraw from the deposit.
     * @param withdrawAddress the address to send withdrawn value.
     * @param withdrawAmount the amount to withdraw.
     */
    function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {
        DepositInfo memory 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");
    }
}

File 2 of 12 : UserOperation.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.12;

/* solhint-disable no-inline-assembly */

    /**
     * User Operation struct
     * @param sender the sender account of this request
     * @param nonce unique value the sender uses to verify it is not a replay.
     * @param initCode if set, the account contract will be created by this constructor
     * @param callData the method call to execute on this account.
     * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp
     * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.
     * @param maxFeePerGas same as EIP-1559 gas parameter
     * @param maxPriorityFeePerGas same as EIP-1559 gas parameter
     * @param paymasterAndData if set, this field hold the paymaster address and "paymaster-specific-data". the paymaster will pay for the transaction instead of the sender
     * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.
     */
    struct UserOperation {

        address sender;
        uint256 nonce;
        bytes initCode;
        bytes callData;
        uint256 callGasLimit;
        uint256 verificationGasLimit;
        uint256 preVerificationGas;
        uint256 maxFeePerGas;
        uint256 maxPriorityFeePerGas;
        bytes paymasterAndData;
        bytes signature;
    }

library UserOperationLib {

    function getSender(UserOperation calldata userOp) internal pure returns (address) {
        address data;
        //read sender from userOp, which is first userOp member (saves 800 gas...)
        assembly {data := calldataload(userOp)}
        return address(uint160(data));
    }

    //relayer/miner might submit the TX with higher priorityFee, but the user should not
    // pay above what he signed for.
    function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {
    unchecked {
        uint256 maxFeePerGas = userOp.maxFeePerGas;
        uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;
        if (maxFeePerGas == maxPriorityFeePerGas) {
            //legacy mode (for networks that don't support basefee opcode)
            return maxFeePerGas;
        }
        return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);
    }
    }

    function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {
        //lighter signature scheme. must match UserOp.ts#packUserOp
        bytes calldata sig = userOp.signature;
        // copy directly the userOp from calldata up to (but not including) the signature.
        // this encoding depends on the ABI encoding of calldata, but is much lighter to copy
        // than referencing each field separately.
        assembly {
            let ofs := userOp
            let len := sub(sub(sig.offset, ofs), 32)
            ret := mload(0x40)
            mstore(0x40, add(ret, add(len, 32)))
            mstore(ret, len)
            calldatacopy(add(ret, 32), ofs, len)
        }
    }

    function hash(UserOperation calldata userOp) internal pure returns (bytes32) {
        return keccak256(pack(userOp));
    }

    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }
}

File 2 of 12 : IAggregator.sol
// 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 called by EntryPoint.simulateUserOperation() if the wallet has an aggregator.
     * First it validates the signature over the userOp. then it return data to be used when creating the handleOps:
     * @param userOp the userOperation received from the user.
     * @param offChainSigCheck if true, don't check signature, and leave it for the Bundler to use an off-chain native library.
     * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.
     *    (usually empty, unless wallet and aggregator support some kind of "multisig"
     * @return sigForAggregation the value to pass (for all wallets) to aggregateSignatures()
     * @return offChainSigInfo in case offChainSigCheck is true, this value should be used by the off-chain signature code (e.g. it contains the sender's publickey)
     */
    function validateUserOpSignature(UserOperation calldata userOp, bool offChainSigCheck)
    external view returns (bytes memory sigForUserOp, bytes memory sigForAggregation, bytes memory offChainSigInfo);

    /**
     * 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 sigsForAggregation array of values returned by validateUserOpSignature() for each op
   * @return aggregatesSignature the aggregated signature
   */
    function aggregateSignatures(bytes[] calldata sigsForAggregation) external view returns (bytes memory aggregatesSignature);
}

File 2 of 12 : IStakeManager.sol
// 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 a wallet)
 * stake is value locked for at least "unstakeDelay" by a paymaster.
 */
interface IStakeManager {

    event Deposited(
        address indexed account,
        uint256 totalDeposit
    );

    event Withdrawn(
        address indexed account,
        address withdrawAddress,
        uint256 amount
    );

    /// Emitted once a stake is scheduled for withdrawal
    event StakeLocked(
        address indexed account,
        uint256 totalStaked,
        uint256 withdrawTime
    );

    /// Emitted once a stake is scheduled for withdrawal
    event StakeUnlocked(
        address indexed account,
        uint256 withdrawTime
    );

    event StakeWithdrawn(
        address indexed account,
        address withdrawAddress,
        uint256 amount
    );

    /**
     * minimum time (in seconds) required to lock a paymaster stake before it can be withdraw.
     */
    function unstakeDelaySec() external returns (uint32);

    /**
     * minimum value required to stake for a paymaster
     */
    function paymasterStake() external returns (uint256);

    /**
     * @param deposit the account's deposit
     * @param staked true if this account is staked as a paymaster
     * @param stake actual amount of ether staked for this paymaster. must be above paymasterStake
     * @param unstakeDelaySec minimum delay to withdraw the stake. must be above the global unstakeDelaySec
     * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked
     * @dev sizes were chosen so that (deposit,staked) fit into one cell (used during handleOps)
     *    and the rest fit into a 2nd cell.
     *    112 bit allows for 2^15 eth
     *    64 bit for full timestamp
     *    32 bit allow 150 years for unstake delay
     */
    struct DepositInfo {
        uint112 deposit;
        bool staked;
        uint112 stake;
        uint32 unstakeDelaySec;
        uint64 withdrawTime;
    }

    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;
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_paymasterStake","type":"uint256"},{"internalType":"uint32","name":"_unstakeDelaySec","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"opIndex","type":"uint256"},{"internalType":"address","name":"paymaster","type":"address"},{"internalType":"string","name":"reason","type":"string"}],"name":"FailedOp","type":"error"},{"inputs":[{"internalType":"address","name":"aggregator","type":"address"}],"name":"SignatureValidationFailed","type":"error"},{"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":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalStaked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withdrawTime","type":"uint256"}],"name":"StakeLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawTime","type":"uint256"}],"name":"StakeUnlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"withdrawAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"requestId","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":"uint256","name":"actualGasCost","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"actualGasPrice","type":"uint256"},{"indexed":false,"internalType":"bool","name":"success","type":"bool"}],"name":"UserOperationEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"revertReason","type":"bytes"}],"name":"UserOperationRevertReason","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"withdrawAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"uint32","name":"_unstakeDelaySec","type":"uint32"}],"name":"addStake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"depositTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"deposits","outputs":[{"internalType":"uint112","name":"deposit","type":"uint112"},{"internalType":"bool","name":"staked","type":"bool"},{"internalType":"uint112","name":"stake","type":"uint112"},{"internalType":"uint32","name":"unstakeDelaySec","type":"uint32"},{"internalType":"uint64","name":"withdrawTime","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getDepositInfo","outputs":[{"components":[{"internalType":"uint112","name":"deposit","type":"uint112"},{"internalType":"bool","name":"staked","type":"bool"},{"internalType":"uint112","name":"stake","type":"uint112"},{"internalType":"uint32","name":"unstakeDelaySec","type":"uint32"},{"internalType":"uint64","name":"withdrawTime","type":"uint64"}],"internalType":"struct IStakeManager.DepositInfo","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"getRequestId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"}],"name":"getSenderAddress","outputs":[{"internalType":"address","name":"sender","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"getSenderStorage","outputs":[{"internalType":"uint256[]","name":"senderStorageCells","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation[]","name":"userOps","type":"tuple[]"},{"internalType":"contract IAggregator","name":"aggregator","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IEntryPoint.UserOpsPerAggregator[]","name":"opsPerAggregator","type":"tuple[]"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"handleAggregatedOps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct UserOperation[]","name":"ops","type":"tuple[]"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"handleOps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"callData","type":"bytes"},{"components":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"callGasLimit","type":"uint256"},{"internalType":"uint256","name":"verificationGasLimit","type":"uint256"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"address","name":"paymaster","type":"address"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"}],"internalType":"struct EntryPoint.MemoryUserOp","name":"mUserOp","type":"tuple"},{"internalType":"bytes32","name":"requestId","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":[],"name":"paymasterStake","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":"userOp","type":"tuple"},{"internalType":"bool","name":"offChainSigCheck","type":"bool"}],"name":"simulateValidation","outputs":[{"internalType":"uint256","name":"preOpGas","type":"uint256"},{"internalType":"uint256","name":"prefund","type":"uint256"},{"internalType":"address","name":"actualAggregator","type":"address"},{"internalType":"bytes","name":"sigForUserOp","type":"bytes"},{"internalType":"bytes","name":"sigForAggregation","type":"bytes"},{"internalType":"bytes","name":"offChainSigInfo","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeDelaySec","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","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"}]

60c06040523480156200001157600080fd5b50604051620062ac380380620062ac833981810160405281019062000037919062000172565b81818063ffffffff1660808163ffffffff16815250508160a08181525050505060008163ffffffff1611620000a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200009a906200021a565b60405180910390fd5b60008211620000e9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000e0906200028c565b60405180910390fd5b5050620002ae565b600080fd5b6000819050919050565b6200010b81620000f6565b81146200011757600080fd5b50565b6000815190506200012b8162000100565b92915050565b600063ffffffff82169050919050565b6200014c8162000131565b81146200015857600080fd5b50565b6000815190506200016c8162000141565b92915050565b600080604083850312156200018c576200018b620000f1565b5b60006200019c858286016200011a565b9250506020620001af858286016200015b565b9150509250929050565b600082825260208201905092915050565b7f696e76616c696420756e7374616b6544656c6179000000000000000000000000600082015250565b600062000202601483620001b9565b91506200020f82620001ca565b602082019050919050565b600060208201905081810360008301526200023581620001f3565b9050919050565b7f696e76616c6964207061796d61737465725374616b6500000000000000000000600082015250565b600062000274601683620001b9565b915062000281826200023c565b602082019050919050565b60006020820190508181036000830152620002a78162000265565b9050919050565b60805160a051615fca620002e260003960008181610661015261094d015260008181610551015261105b0152615fca6000f3fe6080604052600436106101025760003560e01c80635287ce1211610095578063bb9fe6bf11610064578063bb9fe6bf14610351578063c23a5cea14610368578063ec8b5dbf14610391578063fc7e286d146103ce578063ffb01dd91461040f57610112565b80635287ce121461027e57806370a08231146102bb5780639b249f69146102f8578063b760faf91461033557610112565b80631fad948c116100d15780631fad948c146101d8578063205c287814610201578063390b99781461022a5780634b1d7cf51461025557610112565b80630396cb601461011757806314e726341461013357806317c6a987146101705780631d7327561461019b57610112565b366101125761011033610451565b005b600080fd5b610131600480360381019061012c9190613582565b61050d565b005b34801561013f57600080fd5b5061015a600480360381019061015591906135d4565b61090f565b6040516101679190613636565b60405180910390f35b34801561017c57600080fd5b5061018561094b565b604051610192919061366a565b60405180910390f35b3480156101a757600080fd5b506101c260048036038101906101bd919061398c565b61096f565b6040516101cf919061366a565b60405180910390f35b3480156101e457600080fd5b506101ff60048036038101906101fa9190613ab7565b610bb3565b005b34801561020d57600080fd5b5061022860048036038101906102239190613b17565b610d6d565b005b34801561023657600080fd5b5061023f611059565b60405161024c9190613b66565b60405180910390f35b34801561026157600080fd5b5061027c60048036038101906102779190613bd7565b61107d565b005b34801561028a57600080fd5b506102a560048036038101906102a09190613c37565b61142d565b6040516102b29190613d42565b60405180910390f35b3480156102c757600080fd5b506102e260048036038101906102dd9190613c37565b611580565b6040516102ef919061366a565b60405180910390f35b34801561030457600080fd5b5061031f600480360381019061031a9190613d5d565b6115f5565b60405161032c9190613db9565b60405180910390f35b61034f600480360381019061034a9190613c37565b610451565b005b34801561035d57600080fd5b50610366611677565b005b34801561037457600080fd5b5061038f600480360381019061038a9190613dd4565b61182c565b005b34801561039d57600080fd5b506103b860048036038101906103b39190613c37565b611b38565b6040516103c59190613ebf565b60405180910390f35b3480156103da57600080fd5b506103f560048036038101906103f09190613c37565b611bf4565b604051610406959493929190613f0e565b60405180910390f35b34801561041b57600080fd5b5061043660048036038101906104319190613f8d565b611c8f565b60405161044896959493929190614071565b60405180910390f35b61045b8134611e1f565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508173ffffffffffffffffffffffffffffffffffffffff167f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c48260000160009054906101000a90046dffffffffffffffffffffffffffff166040516105019190614122565b60405180910390a25050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1610156105be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b59061419a565b60405180910390fd5b8060010160009054906101000a900463ffffffff1663ffffffff168263ffffffff161015610621576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161061890614206565b60405180910390fd5b60003482600001600f9054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff1661065d9190614255565b90507f00000000000000000000000000000000000000000000000000000000000000008110156106c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b9906142f7565b60405180910390fd5b6dffffffffffffffffffffffffffff80168110610714576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070b90614363565b60405180910390fd5b6040518060a001604052808360000160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff168152602001600115158152602001826dffffffffffffffffffffffffffff1681526020018463ffffffff168152602001600067ffffffffffffffff168152506000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff160217905550602082015181600001600e6101000a81548160ff021916908315150217905550604082015181600001600f6101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff16021790555060608201518160010160006101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff167fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c0182856040516109029291906143b4565b60405180910390a2505050565b600061091a82611f2f565b304660405160200161092e939291906143dd565b604051602081830303815290604052805190602001209050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000805a90506109b36040518060400160405280600e81526020017f696e6e65722068616e646c656f70000000000000000000000000000000000000815250611f48565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109eb57600080fd5b600085600001519050600080898990501115610b4557610a3f6040518060400160405280601481526020017f63616c6c696e67207468652066756e6374696f6e000000000000000000000000815250611f48565b610a4c8260000151611fe1565b600080836000015173ffffffffffffffffffffffffffffffffffffffff1684604001518c8c604051610a7f929190614453565b60006040518083038160008787f1925050503d8060008114610abd576040519150601f19603f3d011682016040523d82523d6000602084013e610ac2565b606091505b5091509150610ad08261207a565b81610b4257600081511115610b3d57836000015173ffffffffffffffffffffffffffffffffffffffff1689602001517f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a201866020015184604051610b3492919061446c565b60405180910390a35b600192505b50505b600087608001515a8503019050610ba46000838a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085612113565b94505050505095945050505050565b600083839050905060008167ffffffffffffffff811115610bd757610bd6613700565b5b604051908082528060200260200182016040528015610c1057816020015b610bfd613428565b815260200190600190039081610bf55790505b50905060005b82811015610c7757610c6981878784818110610c3557610c3461449c565b5b9050602002810190610c4791906144da565b848481518110610c5a57610c5961449c565b5b60200260200101516000612470565b508080600101915050610c16565b50610cb66040518060400160405280601681526020017f63616c6f69646174696f6e20636f6d706c657465643f00000000000000000000815250611f48565b6000805b83811015610d5a57610d006040518060400160405280600f81526020017f6669727374206f7065726174696f6e0000000000000000000000000000000000815250611f48565b610d4981888884818110610d1757610d1661449c565b5b9050602002810190610d2991906144da565b858481518110610d3c57610d3b61449c565b5b602002602001015161262f565b820191508080600101915050610cba565b50610d65848261271f565b505050505050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff16815260200160008201600e9054906101000a900460ff1615151515815260200160008201600f9054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff1681526020016001820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016001820160049054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681525050905080600001516dffffffffffffffffffffffffffff16821115610f0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f039061454f565b60405180910390fd5b8181600001516dffffffffffffffffffffffffffff16610f2c919061456f565b81600001906dffffffffffffffffffffffffffff1690816dffffffffffffffffffffffffffff16815250503373ffffffffffffffffffffffffffffffffffffffff167fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb8484604051610f9f9291906145f8565b60405180910390a260008373ffffffffffffffffffffffffffffffffffffffff1683604051610fcd90614647565b60006040518083038185875af1925050503d806000811461100a576040519150601f19603f3d011682016040523d82523d6000602084013e61100f565b606091505b5050905080611053576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104a906146a8565b60405180910390fd5b50505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008383905090506000805b828110156110e7578585828181106110a4576110a361449c565b5b90506020028101906110b691906146c8565b80600001906110c591906146f0565b9050826110d29190614255565b915080806110df90614753565b915050611089565b5060008167ffffffffffffffff81111561110457611103613700565b5b60405190808252806020026020018201604052801561113d57816020015b61112a613428565b8152602001906001900390816111225790505b5090506000805b8481101561132657368888838181106111605761115f61449c565b5b905060200281019061117291906146c8565b905036600082806000019061118791906146f0565b9150915060008360200160208101906111a091906147da565b9050600083839050905060005b81811015611221576111ff888686848181106111cc576111cb61449c565b5b90506020028101906111de91906144da565b8b8b815181106111f1576111f061449c565b5b602002602001015186612470565b50878061120b90614753565b985050808061121990614753565b9150506111ad565b50600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461130e578173ffffffffffffffffffffffffffffffffffffffff1663e3563a4f85858880604001906112849190614807565b6040518563ffffffff1660e01b81526004016112a39493929190614bc1565b60006040518083038186803b1580156112bb57600080fd5b505afa9250505080156112cc575060015b61130d57816040517f86a9f7500000000000000000000000000000000000000000000000000000000081526004016113049190613db9565b60405180910390fd5b5b5050505050808061131e90614753565b915050611144565b50600080915060005b85811015611418573689898381811061134b5761134a61449c565b5b905060200281019061135d91906146c8565b905036600082806000019061137291906146f0565b91509150600082829050905060005b81811015611400576113d2888585848181106113a05761139f61449c565b5b90506020028101906113b291906144da565b8b8b815181106113c5576113c461449c565b5b602002602001015161262f565b876113dd9190614255565b965087806113ea90614753565b98505080806113f890614753565b915050611381565b5050505050808061141090614753565b91505061132f565b50611423868261271f565b5050505050505050565b611435613460565b6000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff16815260200160008201600e9054906101000a900460ff1615151515815260200160008201600f9054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff1681526020016001820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016001820160049054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff169050919050565b60008073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165c90614c6e565b60405180910390fd5b61166f838361280a565b905092915050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160010160009054906101000a900463ffffffff1663ffffffff161415611717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170e90614cda565b60405180910390fd5b80600001600e9054906101000a900460ff16611768576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175f90614d46565b60405180910390fd5b60008160010160009054906101000a900463ffffffff1663ffffffff16426117909190614d66565b9050808260010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600082600001600e6101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a826040516118209190614dd5565b60405180910390a25050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001600f9054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff169050600081116118e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118db90614e3c565b60405180910390fd5b60008260010160049054906101000a900467ffffffffffffffff1667ffffffffffffffff1611611949576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161194090614ea8565b60405180910390fd5b428260010160049054906101000a900467ffffffffffffffff1667ffffffffffffffff1611156119ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a590614f14565b60405180910390fd5b60008260010160006101000a81548163ffffffff021916908363ffffffff16021790555060008260010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600082600001600f6101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda38483604051611a7e9291906145f8565b60405180910390a260008373ffffffffffffffffffffffffffffffffffffffff1682604051611aac90614647565b60006040518083038185875af1925050503d8060008114611ae9576040519150601f19603f3d011682016040523d82523d6000602084013e611aee565b606091505b5050905080611b32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2990614f80565b60405180910390fd5b50505050565b60606000806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050809150600167ffffffffffffffff811115611b9b57611b9a613700565b5b604051908082528060200260200182016040528015611bc95781602001602082028036833780820191505090505b5092508183600081518110611be157611be061449c565b5b6020026020010181815250505050919050565b60006020528060005260406000206000915090508060000160009054906101000a90046dffffffffffffffffffffffffffff169080600001600e9054906101000a900460ff169080600001600f9054906101000a90046dffffffffffffffffffffffffffff16908060010160009054906101000a900463ffffffff16908060010160049054906101000a900467ffffffffffffffff16905085565b6000806000606080606060005a9050611ca6613428565b611cb460008b836001612470565b9550806040015196508960c001355a83611cce919061456f565b611cd89190614255565b9750611ce26128ec565b600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614611da4578573ffffffffffffffffffffffffffffffffffffffff16636076d43a8b8b6040518363ffffffff1660e01b8152600401611d51929190615104565b600060405180830381865afa158015611d6e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611d9791906151da565b8095508196508297505050505b600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0a90614c6e565b60405180910390fd5b50509295509295509295565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000828260000160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff16611e9d9190614255565b90506dffffffffffffffffffffffffffff8016811115611ef2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee9906152cd565b60405180910390fd5b808260000160006101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff16021790555050505050565b6000611f3a826128f2565b805190602001209050919050565b611fde81604051602401611f5c9190615331565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612934565b50565b61207781604051602401611ff59190613db9565b6040516020818303038152906040527f2c2ecbc2000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612934565b50565b6121108160405160240161208e9190615353565b6040516020818303038152906040527f32458eed000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612934565b50565b6000805a905060008086600001519050600061212e8261295d565b905060008260a001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561217a578260000151935061234e565b80935060008851111561234d57818702955060028081111561219f5761219e61536e565b5b8a60028111156121b2576121b161536e565b5b14612231578073ffffffffffffffffffffffffffffffffffffffff1663a9a2340984606001518c8b8a6040518563ffffffff1660e01b81526004016121f9939291906153e5565b600060405180830381600088803b15801561221357600080fd5b5087f1158015612227573d6000803e3d6000fd5b505050505061234c565b8073ffffffffffffffffffffffffffffffffffffffff1663a9a2340984606001518c8b8a6040518563ffffffff1660e01b8152600401612273939291906153e5565b600060405180830381600088803b15801561228d57600080fd5b5087f19350505050801561229f575060015b61234b576122ab615430565b806308c379a0141561230b57506122c0615452565b806122cb575061230d565b8b82826040517efa072b000000000000000000000000000000000000000000000000000000008152600401612302939291906154e8565b60405180910390fd5b505b8a816040517efa072b000000000000000000000000000000000000000000000000000000008152600401612342929190615572565b60405180910390fd5b5b5b5b5a850387019650818702955085896040015110156123a4578a816040517efa072b00000000000000000000000000000000000000000000000000000000815260040161239b9291906155fa565b60405180910390fd5b6000868a604001510390506123b98582611e1f565b60008060028111156123ce576123cd61536e565b5b8c60028111156123e1576123e061536e565b5b1490508460a0015173ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff168c602001517f33fd4d1f25a5461bea901784a6571de6debc16cd0831932c22c6969cd73ba99488602001518c89876040516124589493929190615636565b60405180910390a45050505050505095945050505050565b6000805a90506000846000015190506124898682612998565b6124928661090f565b85602001818152505060008661010001358760e001358360400151846060015185608001511717171790506effffffffffffffffffffffffffffff8016811115612511576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612508906156c7565b60405180910390fd5b60008061251d84612b40565b905061252c8a8a8a8a85612bb6565b809750819350505061253c6128ec565b6060600073ffffffffffffffffffffffffffffffffffffffff168560a0015173ffffffffffffffffffffffffffffffffffffffff161461258a576125838b8b8b8587612f68565b905061259d565b6040518060200160405280600081525090505b60005a87039050808b60a0013510156125f2578b8660a001516040517efa072b0000000000000000000000000000000000000000000000000000000081526004016125e9929190615759565b60405180910390fd5b828a604001818152505061260582613217565b8a60600181815250508a60c001355a8803018a608001818152505050505050505050949350505050565b6000805a905061263e81613221565b600061264d84606001516132ba565b90503073ffffffffffffffffffffffffffffffffffffffff16631d73275686806060019061267b9190614807565b87856040518563ffffffff1660e01b815260040161269c94939291906158b3565b6020604051808303816000875af19250505080156126d857506040513d601f19601f820116820180604052508101906126d59190615911565b60015b61271157600084608001515a846126ef919061456f565b6126f99190614255565b9050612709876002878585612113565b935050612716565b809350505b50509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561278f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127869061598a565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516127b590614647565b60006040518083038185875af1925050503d80600081146127f2576040519150601f19603f3d011682016040523d82523d6000602084013e6127f7565b606091505b505090508061280557600080fd5b505050565b6000808383600090601492612821939291906159b4565b9061282c9190615a33565b60601c9050600084846014908092612846939291906159b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505090506000602060008351602085016000875af190506000519350806128e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128da90615ade565b60405180910390fd5b50505092915050565b43600052565b6060366000838061014001906129089190614807565b915091508360208184030360405194506020810185016040528085528082602087013750505050919050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b6000808260c00151905060008360e00151905080821415612982578192505050612993565b61298e824883016132c4565b925050505b919050565b8160000160208101906129ab9190613c37565b816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050816020013581602001818152505081608001358160400181815250508160a001358160600181815250508160c001358160800181815250508160e001358160c00181815250508161010001358160e001818152505036600083806101200190612a4b9190614807565b915091506000828290501115612b00576014828290501015612aa2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a9990615b4a565b60405180910390fd5b8181600090601492612ab6939291906159b4565b90612ac19190615a33565b60601c8360a0019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050612b3a565b60008360a0019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b50505050565b600080600073ffffffffffffffffffffffffffffffffffffffff168360a0015173ffffffffffffffffffffffffffffffffffffffff161415612b83576001612b86565b60035b60ff1690506000836080015182856060015102856040015101019050612bab8461295d565b810292505050919050565b60008060005a9050600086600001519050612be081898060400190612bdb9190614807565b6132dd565b600173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415612c9a57806000015173ffffffffffffffffffffffffffffffffffffffff16633ad59dbc6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612c8157506040513d601f19601f82011682018060405250810190612c7e9190615b7f565b60015b612c915760009250829550612c99565b809350839650505b5b6000808260000151905060008360a001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612d05576000612ced83611580565b9050888111612cfe57808903612d01565b60005b9350505b8173ffffffffffffffffffffffffffffffffffffffff16630825d1fc85606001518d8d602001518d886040518663ffffffff1660e01b8152600401612d4d9493929190615bac565b600060405180830381600088803b158015612d6757600080fd5b5087f193505050508015612d79575060015b612e2757612d85615430565b806308c379a01415612de65750612d9a615452565b80612da55750612de8565b8c6000826040517efa072b000000000000000000000000000000000000000000000000000000008152600401612ddd939291906154e8565b60405180910390fd5b505b8b60006040517efa072b000000000000000000000000000000000000000000000000000000008152600401612e1e929190615c1b565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612f545760008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff169050808a1115612f18578d60006040517efa072b000000000000000000000000000000000000000000000000000000008152600401612f0f929190615ca3565b60405180910390fd5b8981038260000160006101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff16021790555050505b5a8503965050505050509550959350505050565b606060008460000151905060008160a00151905060008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff169050600082600001600e9054906101000a900460ff1690508061304a578a846040517efa072b000000000000000000000000000000000000000000000000000000008152600401613041929190615cdf565b60405180910390fd5b87821015613090578a846040517efa072b000000000000000000000000000000000000000000000000000000008152600401613087929190615d67565b60405180910390fd5b8782038360000160006101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff16021790555060008786606001510390508473ffffffffffffffffffffffffffffffffffffffff1663f465c77e828d8d602001518d6040518563ffffffff1660e01b815260040161311693929190615da3565b60006040518083038160008887f19350505050801561315857506040513d6000823e3d601f19601f820116820180604052508101906131559190615de1565b60015b61320457613164615430565b806308c379a014156131c45750613179615452565b8061318457506131c6565b8c86826040517efa072b0000000000000000000000000000000000000000000000000000000081526004016131bb939291906154e8565b60405180910390fd5b505b8b856040517efa072b0000000000000000000000000000000000000000000000000000000081526004016131fb929190615c1b565b60405180910390fd5b8097505050505050505095945050505050565b6000819050919050565b6132b781604051602401613235919061366a565b6040516020818303038152906040527ff82c50f1000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612934565b50565b6060819050919050565b60008183106132d357816132d5565b825b905092915050565b60008282905014613423576000836000015173ffffffffffffffffffffffffffffffffffffffff163b14613346576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161333d90615e76565b60405180910390fd5b6000613352838361280a565b9050836000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146133c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133bd90615f08565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff163b1415613421576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161341890615f74565b60405180910390fd5b505b505050565b6040518060a0016040528061343b6134c1565b8152602001600080191681526020016000815260200160008152602001600081525090565b6040518060a0016040528060006dffffffffffffffffffffffffffff16815260200160001515815260200160006dffffffffffffffffffffffffffff168152602001600063ffffffff168152602001600067ffffffffffffffff1681525090565b604051806101000160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b600063ffffffff82169050919050565b61355f81613546565b811461356a57600080fd5b50565b60008135905061357c81613556565b92915050565b6000602082840312156135985761359761353c565b5b60006135a68482850161356d565b91505092915050565b600080fd5b600061016082840312156135cb576135ca6135af565b5b81905092915050565b6000602082840312156135ea576135e961353c565b5b600082013567ffffffffffffffff81111561360857613607613541565b5b613614848285016135b4565b91505092915050565b6000819050919050565b6136308161361d565b82525050565b600060208201905061364b6000830184613627565b92915050565b6000819050919050565b61366481613651565b82525050565b600060208201905061367f600083018461365b565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126136aa576136a9613685565b5b8235905067ffffffffffffffff8111156136c7576136c661368a565b5b6020830191508360018202830111156136e3576136e261368f565b5b9250929050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613738826136ef565b810181811067ffffffffffffffff8211171561375757613756613700565b5b80604052505050565b600061376a613532565b9050613776828261372f565b919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006137a68261377b565b9050919050565b6137b68161379b565b81146137c157600080fd5b50565b6000813590506137d3816137ad565b92915050565b6137e281613651565b81146137ed57600080fd5b50565b6000813590506137ff816137d9565b92915050565b6000610100828403121561381c5761381b6136ea565b5b613827610100613760565b90506000613837848285016137c4565b600083015250602061384b848285016137f0565b602083015250604061385f848285016137f0565b6040830152506060613873848285016137f0565b6060830152506080613887848285016137f0565b60808301525060a061389b848285016137c4565b60a08301525060c06138af848285016137f0565b60c08301525060e06138c3848285016137f0565b60e08301525092915050565b6138d88161361d565b81146138e357600080fd5b50565b6000813590506138f5816138cf565b92915050565b60006101808284031215613912576139116136ea565b5b61391c60a0613760565b9050600061392c84828501613805565b600083015250610100613941848285016138e6565b602083015250610120613956848285016137f0565b60408301525061014061396b848285016137f0565b606083015250610160613980848285016137f0565b60808301525092915050565b60008060008060006101c086880312156139a9576139a861353c565b5b600086013567ffffffffffffffff8111156139c7576139c6613541565b5b6139d388828901613694565b955095505060206139e6888289016138fb565b9350506101a086013567ffffffffffffffff811115613a0857613a07613541565b5b613a1488828901613694565b92509250509295509295909350565b60008083601f840112613a3957613a38613685565b5b8235905067ffffffffffffffff811115613a5657613a5561368a565b5b602083019150836020820283011115613a7257613a7161368f565b5b9250929050565b6000613a848261377b565b9050919050565b613a9481613a79565b8114613a9f57600080fd5b50565b600081359050613ab181613a8b565b92915050565b600080600060408486031215613ad057613acf61353c565b5b600084013567ffffffffffffffff811115613aee57613aed613541565b5b613afa86828701613a23565b93509350506020613b0d86828701613aa2565b9150509250925092565b60008060408385031215613b2e57613b2d61353c565b5b6000613b3c85828601613aa2565b9250506020613b4d858286016137f0565b9150509250929050565b613b6081613546565b82525050565b6000602082019050613b7b6000830184613b57565b92915050565b60008083601f840112613b9757613b96613685565b5b8235905067ffffffffffffffff811115613bb457613bb361368a565b5b602083019150836020820283011115613bd057613bcf61368f565b5b9250929050565b600080600060408486031215613bf057613bef61353c565b5b600084013567ffffffffffffffff811115613c0e57613c0d613541565b5b613c1a86828701613b81565b93509350506020613c2d86828701613aa2565b9150509250925092565b600060208284031215613c4d57613c4c61353c565b5b6000613c5b848285016137c4565b91505092915050565b60006dffffffffffffffffffffffffffff82169050919050565b613c8781613c64565b82525050565b60008115159050919050565b613ca281613c8d565b82525050565b613cb181613546565b82525050565b600067ffffffffffffffff82169050919050565b613cd481613cb7565b82525050565b60a082016000820151613cf06000850182613c7e565b506020820151613d036020850182613c99565b506040820151613d166040850182613c7e565b506060820151613d296060850182613ca8565b506080820151613d3c6080850182613ccb565b50505050565b600060a082019050613d576000830184613cda565b92915050565b60008060208385031215613d7457613d7361353c565b5b600083013567ffffffffffffffff811115613d9257613d91613541565b5b613d9e85828601613694565b92509250509250929050565b613db38161379b565b82525050565b6000602082019050613dce6000830184613daa565b92915050565b600060208284031215613dea57613de961353c565b5b6000613df884828501613aa2565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613e3681613651565b82525050565b6000613e488383613e2d565b60208301905092915050565b6000602082019050919050565b6000613e6c82613e01565b613e768185613e0c565b9350613e8183613e1d565b8060005b83811015613eb2578151613e998882613e3c565b9750613ea483613e54565b925050600181019050613e85565b5085935050505092915050565b60006020820190508181036000830152613ed98184613e61565b905092915050565b613eea81613c64565b82525050565b613ef981613c8d565b82525050565b613f0881613cb7565b82525050565b600060a082019050613f236000830188613ee1565b613f306020830187613ef0565b613f3d6040830186613ee1565b613f4a6060830185613b57565b613f576080830184613eff565b9695505050505050565b613f6a81613c8d565b8114613f7557600080fd5b50565b600081359050613f8781613f61565b92915050565b60008060408385031215613fa457613fa361353c565b5b600083013567ffffffffffffffff811115613fc257613fc1613541565b5b613fce858286016135b4565b9250506020613fdf85828601613f78565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015614023578082015181840152602081019050614008565b83811115614032576000848401525b50505050565b600061404382613fe9565b61404d8185613ff4565b935061405d818560208601614005565b614066816136ef565b840191505092915050565b600060c082019050614086600083018961365b565b614093602083018861365b565b6140a06040830187613daa565b81810360608301526140b28186614038565b905081810360808301526140c68185614038565b905081810360a08301526140da8184614038565b9050979650505050505050565b6000819050919050565b600061410c61410761410284613c64565b6140e7565b613651565b9050919050565b61411c816140f1565b82525050565b60006020820190506141376000830184614113565b92915050565b600082825260208201905092915050565b7f756e7374616b652064656c617920746f6f206c6f770000000000000000000000600082015250565b600061418460158361413d565b915061418f8261414e565b602082019050919050565b600060208201905081810360008301526141b381614177565b9050919050565b7f63616e6e6f7420646563726561736520756e7374616b652074696d6500000000600082015250565b60006141f0601c8361413d565b91506141fb826141ba565b602082019050919050565b6000602082019050818103600083015261421f816141e3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061426082613651565b915061426b83613651565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156142a05761429f614226565b5b828201905092915050565b7f7374616b652076616c756520746f6f206c6f7700000000000000000000000000600082015250565b60006142e160138361413d565b91506142ec826142ab565b602082019050919050565b60006020820190508181036000830152614310816142d4565b9050919050565b7f7374616b65206f766572666c6f77000000000000000000000000000000000000600082015250565b600061434d600e8361413d565b915061435882614317565b602082019050919050565b6000602082019050818103600083015261437c81614340565b9050919050565b600061439e61439961439484613546565b6140e7565b613651565b9050919050565b6143ae81614383565b82525050565b60006040820190506143c9600083018561365b565b6143d660208301846143a5565b9392505050565b60006060820190506143f26000830186613627565b6143ff6020830185613daa565b61440c604083018461365b565b949350505050565b600081905092915050565b82818337600083830152505050565b600061443a8385614414565b935061444783858461441f565b82840190509392505050565b600061446082848661442e565b91508190509392505050565b6000604082019050614481600083018561365b565b81810360208301526144938184614038565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b600082356001610160038336030381126144f7576144f66144cb565b5b80830191505092915050565b7f576974686472617720616d6f756e7420746f6f206c6172676500000000000000600082015250565b600061453960198361413d565b915061454482614503565b602082019050919050565b600060208201905081810360008301526145688161452c565b9050919050565b600061457a82613651565b915061458583613651565b92508282101561459857614597614226565b5b828203905092915050565b60006145be6145b96145b48461377b565b6140e7565b61377b565b9050919050565b60006145d0826145a3565b9050919050565b60006145e2826145c5565b9050919050565b6145f2816145d7565b82525050565b600060408201905061460d60008301856145e9565b61461a602083018461365b565b9392505050565b50565b6000614631600083614414565b915061463c82614621565b600082019050919050565b600061465282614624565b9150819050919050565b7f6661696c656420746f2077697468647261770000000000000000000000000000600082015250565b600061469260128361413d565b915061469d8261465c565b602082019050919050565b600060208201905081810360008301526146c181614685565b9050919050565b6000823560016060038336030381126146e4576146e36144cb565b5b80830191505092915050565b6000808335600160200384360303811261470d5761470c6144cb565b5b80840192508235915067ffffffffffffffff82111561472f5761472e6144d0565b5b60208301925060208202360383131561474b5761474a6144d5565b5b509250929050565b600061475e82613651565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561479157614790614226565b5b600182019050919050565b60006147a78261379b565b9050919050565b6147b78161479c565b81146147c257600080fd5b50565b6000813590506147d4816147ae565b92915050565b6000602082840312156147f0576147ef61353c565b5b60006147fe848285016147c5565b91505092915050565b60008083356001602003843603038112614824576148236144cb565b5b80840192508235915067ffffffffffffffff821115614846576148456144d0565b5b602083019250600182023603831315614862576148616144d5565b5b509250929050565b600082825260208201905092915050565b6000819050919050565b600061489460208401846137c4565b905092915050565b6148a58161379b565b82525050565b60006148ba60208401846137f0565b905092915050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126148ee576148ed6148cc565b5b83810192508235915060208301925067ffffffffffffffff821115614916576149156148c2565b5b60018202360384131561492c5761492b6148c7565b5b509250929050565b600082825260208201905092915050565b60006149518385614934565b935061495e83858461441f565b614967836136ef565b840190509392505050565b600061016083016149866000840184614885565b614993600086018261489c565b506149a160208401846148ab565b6149ae6020860182613e2d565b506149bc60408401846148d1565b85830360408701526149cf838284614945565b925050506149e060608401846148d1565b85830360608701526149f3838284614945565b92505050614a0460808401846148ab565b614a116080860182613e2d565b50614a1f60a08401846148ab565b614a2c60a0860182613e2d565b50614a3a60c08401846148ab565b614a4760c0860182613e2d565b50614a5560e08401846148ab565b614a6260e0860182613e2d565b50614a716101008401846148ab565b614a7f610100860182613e2d565b50614a8e6101208401846148d1565b858303610120870152614aa2838284614945565b92505050614ab46101408401846148d1565b858303610140870152614ac8838284614945565b925050508091505092915050565b6000614ae28383614972565b905092915050565b60008235600161016003833603038112614b0757614b066148cc565b5b82810191505092915050565b6000602082019050919050565b6000614b2c838561486a565b935083602084028501614b3e8461487b565b8060005b87811015614b82578484038952614b598284614aea565b614b638582614ad6565b9450614b6e83614b13565b925060208a01995050600181019050614b42565b50829750879450505050509392505050565b6000614ba08385613ff4565b9350614bad83858461441f565b614bb6836136ef565b840190509392505050565b60006040820190508181036000830152614bdc818688614b20565b90508181036020830152614bf1818486614b94565b905095945050505050565b7f6d7573742062652063616c6c6564206f66662d636861696e207769746820667260008201527f6f6d3d7a65726f2d616464720000000000000000000000000000000000000000602082015250565b6000614c58602c8361413d565b9150614c6382614bfc565b604082019050919050565b60006020820190508181036000830152614c8781614c4b565b9050919050565b7f6e6f74207374616b656400000000000000000000000000000000000000000000600082015250565b6000614cc4600a8361413d565b9150614ccf82614c8e565b602082019050919050565b60006020820190508181036000830152614cf381614cb7565b9050919050565b7f616c726561647920756e7374616b696e67000000000000000000000000000000600082015250565b6000614d3060118361413d565b9150614d3b82614cfa565b602082019050919050565b60006020820190508181036000830152614d5f81614d23565b9050919050565b6000614d7182613cb7565b9150614d7c83613cb7565b92508267ffffffffffffffff03821115614d9957614d98614226565b5b828201905092915050565b6000614dbf614dba614db584613cb7565b6140e7565b613651565b9050919050565b614dcf81614da4565b82525050565b6000602082019050614dea6000830184614dc6565b92915050565b7f4e6f207374616b6520746f207769746864726177000000000000000000000000600082015250565b6000614e2660148361413d565b9150614e3182614df0565b602082019050919050565b60006020820190508181036000830152614e5581614e19565b9050919050565b7f6d7573742063616c6c20756e6c6f636b5374616b652829206669727374000000600082015250565b6000614e92601d8361413d565b9150614e9d82614e5c565b602082019050919050565b60006020820190508181036000830152614ec181614e85565b9050919050565b7f5374616b65207769746864726177616c206973206e6f74206475650000000000600082015250565b6000614efe601b8361413d565b9150614f0982614ec8565b602082019050919050565b60006020820190508181036000830152614f2d81614ef1565b9050919050565b7f6661696c656420746f207769746864726177207374616b650000000000000000600082015250565b6000614f6a60188361413d565b9150614f7582614f34565b602082019050919050565b60006020820190508181036000830152614f9981614f5d565b9050919050565b60006101608301614fb46000840184614885565b614fc1600086018261489c565b50614fcf60208401846148ab565b614fdc6020860182613e2d565b50614fea60408401846148d1565b8583036040870152614ffd838284614945565b9250505061500e60608401846148d1565b8583036060870152615021838284614945565b9250505061503260808401846148ab565b61503f6080860182613e2d565b5061504d60a08401846148ab565b61505a60a0860182613e2d565b5061506860c08401846148ab565b61507560c0860182613e2d565b5061508360e08401846148ab565b61509060e0860182613e2d565b5061509f6101008401846148ab565b6150ad610100860182613e2d565b506150bc6101208401846148d1565b8583036101208701526150d0838284614945565b925050506150e26101408401846148d1565b8583036101408701526150f6838284614945565b925050508091505092915050565b6000604082019050818103600083015261511e8185614fa0565b905061512d6020830184613ef0565b9392505050565b600080fd5b600067ffffffffffffffff82111561515457615153613700565b5b61515d826136ef565b9050602081019050919050565b600061517d61517884615139565b613760565b90508281526020810184848401111561519957615198615134565b5b6151a4848285614005565b509392505050565b600082601f8301126151c1576151c0613685565b5b81516151d184826020860161516a565b91505092915050565b6000806000606084860312156151f3576151f261353c565b5b600084015167ffffffffffffffff81111561521157615210613541565b5b61521d868287016151ac565b935050602084015167ffffffffffffffff81111561523e5761523d613541565b5b61524a868287016151ac565b925050604084015167ffffffffffffffff81111561526b5761526a613541565b5b615277868287016151ac565b9150509250925092565b7f6465706f736974206f766572666c6f7700000000000000000000000000000000600082015250565b60006152b760108361413d565b91506152c282615281565b602082019050919050565b600060208201905081810360008301526152e6816152aa565b9050919050565b600081519050919050565b6000615303826152ed565b61530d818561413d565b935061531d818560208601614005565b615326816136ef565b840191505092915050565b6000602082019050818103600083015261534b81846152f8565b905092915050565b60006020820190506153686000830184613ef0565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600381106153ae576153ad61536e565b5b50565b60008190506153bf8261539d565b919050565b60006153cf826153b1565b9050919050565b6153df816153c4565b82525050565b60006060820190506153fa60008301866153d6565b818103602083015261540c8185614038565b905061541b604083018461365b565b949350505050565b60008160e01c9050919050565b600060033d111561544f5760046000803e61544c600051615423565b90505b90565b600060443d1015615462576154e5565b61546a613532565b60043d036004823e80513d602482011167ffffffffffffffff821117156154925750506154e5565b808201805167ffffffffffffffff8111156154b057505050506154e5565b80602083010160043d0385018111156154cd5750505050506154e5565b6154dc8260200185018661372f565b82955050505050505b90565b60006060820190506154fd600083018661365b565b61550a6020830185613daa565b818103604083015261551c81846152f8565b9050949350505050565b7f706f73744f702072657665727400000000000000000000000000000000000000600082015250565b600061555c600d8361413d565b915061556782615526565b602082019050919050565b6000606082019050615587600083018561365b565b6155946020830184613daa565b81810360408301526155a58161554f565b90509392505050565b7f70726566756e642062656c6f772061637475616c476173436f73740000000000600082015250565b60006155e4601b8361413d565b91506155ef826155ae565b602082019050919050565b600060608201905061560f600083018561365b565b61561c6020830184613daa565b818103604083015261562d816155d7565b90509392505050565b600060808201905061564b600083018761365b565b615658602083018661365b565b615665604083018561365b565b6156726060830184613ef0565b95945050505050565b7f6761732076616c756573206f766572666c6f7700000000000000000000000000600082015250565b60006156b160138361413d565b91506156bc8261567b565b602082019050919050565b600060208201905081810360008301526156e0816156a4565b9050919050565b7f55736564206d6f7265207468616e20766572696669636174696f6e4761734c6960008201527f6d69740000000000000000000000000000000000000000000000000000000000602082015250565b600061574360238361413d565b915061574e826156e7565b604082019050919050565b600060608201905061576e600083018561365b565b61577b6020830184613daa565b818103604083015261578c81615736565b90509392505050565b610100820160008201516157ac600085018261489c565b5060208201516157bf6020850182613e2d565b5060408201516157d26040850182613e2d565b5060608201516157e56060850182613e2d565b5060808201516157f86080850182613e2d565b5060a082015161580b60a085018261489c565b5060c082015161581e60c0850182613e2d565b5060e082015161583160e0850182613e2d565b50505050565b6158408161361d565b82525050565b6101808201600082015161585d6000850182615795565b506020820151615871610100850182615837565b506040820151615885610120850182613e2d565b506060820151615899610140850182613e2d565b5060808201516158ad610160850182613e2d565b50505050565b60006101c08201905081810360008301526158cf818688614b94565b90506158de6020830185615846565b8181036101a08301526158f18184614038565b905095945050505050565b60008151905061590b816137d9565b92915050565b6000602082840312156159275761592661353c565b5b6000615935848285016158fc565b91505092915050565b7f696e76616c69642062656e656669636961727900000000000000000000000000600082015250565b600061597460138361413d565b915061597f8261593e565b602082019050919050565b600060208201905081810360008301526159a381615967565b9050919050565b600080fd5b600080fd5b600080858511156159c8576159c76159aa565b5b838611156159d9576159d86159af565b5b6001850283019150848603905094509492505050565b600082905092915050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b600082821b905092915050565b6000615a3f83836159ef565b82615a4a81356159fa565b92506014821015615a8a57615a857fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802615a26565b831692505b505092915050565b7f696e6974436f6465206661696c65640000000000000000000000000000000000600082015250565b6000615ac8600f8361413d565b9150615ad382615a92565b602082019050919050565b60006020820190508181036000830152615af781615abb565b9050919050565b7f696e76616c6964207061796d6173746572416e64446174610000000000000000600082015250565b6000615b3460188361413d565b9150615b3f82615afe565b602082019050919050565b60006020820190508181036000830152615b6381615b27565b9050919050565b600081519050615b79816137ad565b92915050565b600060208284031215615b9557615b9461353c565b5b6000615ba384828501615b6a565b91505092915050565b60006080820190508181036000830152615bc68187614fa0565b9050615bd56020830186613627565b615be26040830185613daa565b615bef606083018461365b565b95945050505050565b6000615c0560008361413d565b9150615c1082614621565b600082019050919050565b6000606082019050615c30600083018561365b565b615c3d6020830184613daa565b8181036040830152615c4e81615bf8565b90509392505050565b7f77616c6c6574206469646e2774207061792070726566756e6400000000000000600082015250565b6000615c8d60198361413d565b9150615c9882615c57565b602082019050919050565b6000606082019050615cb8600083018561365b565b615cc56020830184613daa565b8181036040830152615cd681615c80565b90509392505050565b6000606082019050615cf4600083018561365b565b615d016020830184613daa565b8181036040830152615d1281614cb7565b90509392505050565b7f7061796d6173746572206465706f73697420746f6f206c6f7700000000000000600082015250565b6000615d5160198361413d565b9150615d5c82615d1b565b602082019050919050565b6000606082019050615d7c600083018561365b565b615d896020830184613daa565b8181036040830152615d9a81615d44565b90509392505050565b60006060820190508181036000830152615dbd8186614fa0565b9050615dcc6020830185613627565b615dd9604083018461365b565b949350505050565b600060208284031215615df757615df661353c565b5b600082015167ffffffffffffffff811115615e1557615e14613541565b5b615e21848285016151ac565b91505092915050565b7f73656e64657220616c726561647920636f6e7374727563746564000000000000600082015250565b6000615e60601a8361413d565b9150615e6b82615e2a565b602082019050919050565b60006020820190508181036000830152615e8f81615e53565b9050919050565b7f73656e64657220646f65736e2774206d6174636820696e6974436f646520616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000615ef260258361413d565b9150615efd82615e96565b604082019050919050565b60006020820190508181036000830152615f2181615ee5565b9050919050565b7f696e6974436f6465206661696c656420746f206372656174652073656e646572600082015250565b6000615f5e60208361413d565b9150615f6982615f28565b602082019050919050565b60006020820190508181036000830152615f8d81615f51565b905091905056fea26469706673582212208addda0544987f7a9824b18bd497b7afe098b10463fe6f24ed242f01f364b22e64736f6c634300080c003300000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000000000000000000000000000000000000000005

Deployed Bytecode

0x6080604052600436106101025760003560e01c80635287ce1211610095578063bb9fe6bf11610064578063bb9fe6bf14610351578063c23a5cea14610368578063ec8b5dbf14610391578063fc7e286d146103ce578063ffb01dd91461040f57610112565b80635287ce121461027e57806370a08231146102bb5780639b249f69146102f8578063b760faf91461033557610112565b80631fad948c116100d15780631fad948c146101d8578063205c287814610201578063390b99781461022a5780634b1d7cf51461025557610112565b80630396cb601461011757806314e726341461013357806317c6a987146101705780631d7327561461019b57610112565b366101125761011033610451565b005b600080fd5b610131600480360381019061012c9190613582565b61050d565b005b34801561013f57600080fd5b5061015a600480360381019061015591906135d4565b61090f565b6040516101679190613636565b60405180910390f35b34801561017c57600080fd5b5061018561094b565b604051610192919061366a565b60405180910390f35b3480156101a757600080fd5b506101c260048036038101906101bd919061398c565b61096f565b6040516101cf919061366a565b60405180910390f35b3480156101e457600080fd5b506101ff60048036038101906101fa9190613ab7565b610bb3565b005b34801561020d57600080fd5b5061022860048036038101906102239190613b17565b610d6d565b005b34801561023657600080fd5b5061023f611059565b60405161024c9190613b66565b60405180910390f35b34801561026157600080fd5b5061027c60048036038101906102779190613bd7565b61107d565b005b34801561028a57600080fd5b506102a560048036038101906102a09190613c37565b61142d565b6040516102b29190613d42565b60405180910390f35b3480156102c757600080fd5b506102e260048036038101906102dd9190613c37565b611580565b6040516102ef919061366a565b60405180910390f35b34801561030457600080fd5b5061031f600480360381019061031a9190613d5d565b6115f5565b60405161032c9190613db9565b60405180910390f35b61034f600480360381019061034a9190613c37565b610451565b005b34801561035d57600080fd5b50610366611677565b005b34801561037457600080fd5b5061038f600480360381019061038a9190613dd4565b61182c565b005b34801561039d57600080fd5b506103b860048036038101906103b39190613c37565b611b38565b6040516103c59190613ebf565b60405180910390f35b3480156103da57600080fd5b506103f560048036038101906103f09190613c37565b611bf4565b604051610406959493929190613f0e565b60405180910390f35b34801561041b57600080fd5b5061043660048036038101906104319190613f8d565b611c8f565b60405161044896959493929190614071565b60405180910390f35b61045b8134611e1f565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508173ffffffffffffffffffffffffffffffffffffffff167f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c48260000160009054906101000a90046dffffffffffffffffffffffffffff166040516105019190614122565b60405180910390a25050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090507f000000000000000000000000000000000000000000000000000000000000000563ffffffff168263ffffffff1610156105be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b59061419a565b60405180910390fd5b8060010160009054906101000a900463ffffffff1663ffffffff168263ffffffff161015610621576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161061890614206565b60405180910390fd5b60003482600001600f9054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff1661065d9190614255565b90507f00000000000000000000000000000000000000000000000000b1a2bc2ec500008110156106c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b9906142f7565b60405180910390fd5b6dffffffffffffffffffffffffffff80168110610714576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070b90614363565b60405180910390fd5b6040518060a001604052808360000160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff168152602001600115158152602001826dffffffffffffffffffffffffffff1681526020018463ffffffff168152602001600067ffffffffffffffff168152506000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff160217905550602082015181600001600e6101000a81548160ff021916908315150217905550604082015181600001600f6101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff16021790555060608201518160010160006101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff167fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c0182856040516109029291906143b4565b60405180910390a2505050565b600061091a82611f2f565b304660405160200161092e939291906143dd565b604051602081830303815290604052805190602001209050919050565b7f00000000000000000000000000000000000000000000000000b1a2bc2ec5000081565b6000805a90506109b36040518060400160405280600e81526020017f696e6e65722068616e646c656f70000000000000000000000000000000000000815250611f48565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109eb57600080fd5b600085600001519050600080898990501115610b4557610a3f6040518060400160405280601481526020017f63616c6c696e67207468652066756e6374696f6e000000000000000000000000815250611f48565b610a4c8260000151611fe1565b600080836000015173ffffffffffffffffffffffffffffffffffffffff1684604001518c8c604051610a7f929190614453565b60006040518083038160008787f1925050503d8060008114610abd576040519150601f19603f3d011682016040523d82523d6000602084013e610ac2565b606091505b5091509150610ad08261207a565b81610b4257600081511115610b3d57836000015173ffffffffffffffffffffffffffffffffffffffff1689602001517f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a201866020015184604051610b3492919061446c565b60405180910390a35b600192505b50505b600087608001515a8503019050610ba46000838a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085612113565b94505050505095945050505050565b600083839050905060008167ffffffffffffffff811115610bd757610bd6613700565b5b604051908082528060200260200182016040528015610c1057816020015b610bfd613428565b815260200190600190039081610bf55790505b50905060005b82811015610c7757610c6981878784818110610c3557610c3461449c565b5b9050602002810190610c4791906144da565b848481518110610c5a57610c5961449c565b5b60200260200101516000612470565b508080600101915050610c16565b50610cb66040518060400160405280601681526020017f63616c6f69646174696f6e20636f6d706c657465643f00000000000000000000815250611f48565b6000805b83811015610d5a57610d006040518060400160405280600f81526020017f6669727374206f7065726174696f6e0000000000000000000000000000000000815250611f48565b610d4981888884818110610d1757610d1661449c565b5b9050602002810190610d2991906144da565b858481518110610d3c57610d3b61449c565b5b602002602001015161262f565b820191508080600101915050610cba565b50610d65848261271f565b505050505050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff16815260200160008201600e9054906101000a900460ff1615151515815260200160008201600f9054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff1681526020016001820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016001820160049054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681525050905080600001516dffffffffffffffffffffffffffff16821115610f0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f039061454f565b60405180910390fd5b8181600001516dffffffffffffffffffffffffffff16610f2c919061456f565b81600001906dffffffffffffffffffffffffffff1690816dffffffffffffffffffffffffffff16815250503373ffffffffffffffffffffffffffffffffffffffff167fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb8484604051610f9f9291906145f8565b60405180910390a260008373ffffffffffffffffffffffffffffffffffffffff1683604051610fcd90614647565b60006040518083038185875af1925050503d806000811461100a576040519150601f19603f3d011682016040523d82523d6000602084013e61100f565b606091505b5050905080611053576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104a906146a8565b60405180910390fd5b50505050565b7f000000000000000000000000000000000000000000000000000000000000000581565b60008383905090506000805b828110156110e7578585828181106110a4576110a361449c565b5b90506020028101906110b691906146c8565b80600001906110c591906146f0565b9050826110d29190614255565b915080806110df90614753565b915050611089565b5060008167ffffffffffffffff81111561110457611103613700565b5b60405190808252806020026020018201604052801561113d57816020015b61112a613428565b8152602001906001900390816111225790505b5090506000805b8481101561132657368888838181106111605761115f61449c565b5b905060200281019061117291906146c8565b905036600082806000019061118791906146f0565b9150915060008360200160208101906111a091906147da565b9050600083839050905060005b81811015611221576111ff888686848181106111cc576111cb61449c565b5b90506020028101906111de91906144da565b8b8b815181106111f1576111f061449c565b5b602002602001015186612470565b50878061120b90614753565b985050808061121990614753565b9150506111ad565b50600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461130e578173ffffffffffffffffffffffffffffffffffffffff1663e3563a4f85858880604001906112849190614807565b6040518563ffffffff1660e01b81526004016112a39493929190614bc1565b60006040518083038186803b1580156112bb57600080fd5b505afa9250505080156112cc575060015b61130d57816040517f86a9f7500000000000000000000000000000000000000000000000000000000081526004016113049190613db9565b60405180910390fd5b5b5050505050808061131e90614753565b915050611144565b50600080915060005b85811015611418573689898381811061134b5761134a61449c565b5b905060200281019061135d91906146c8565b905036600082806000019061137291906146f0565b91509150600082829050905060005b81811015611400576113d2888585848181106113a05761139f61449c565b5b90506020028101906113b291906144da565b8b8b815181106113c5576113c461449c565b5b602002602001015161262f565b876113dd9190614255565b965087806113ea90614753565b98505080806113f890614753565b915050611381565b5050505050808061141090614753565b91505061132f565b50611423868261271f565b5050505050505050565b611435613460565b6000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff16815260200160008201600e9054906101000a900460ff1615151515815260200160008201600f9054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff1681526020016001820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016001820160049054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff169050919050565b60008073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165c90614c6e565b60405180910390fd5b61166f838361280a565b905092915050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160010160009054906101000a900463ffffffff1663ffffffff161415611717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170e90614cda565b60405180910390fd5b80600001600e9054906101000a900460ff16611768576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175f90614d46565b60405180910390fd5b60008160010160009054906101000a900463ffffffff1663ffffffff16426117909190614d66565b9050808260010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600082600001600e6101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a826040516118209190614dd5565b60405180910390a25050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001600f9054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff169050600081116118e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118db90614e3c565b60405180910390fd5b60008260010160049054906101000a900467ffffffffffffffff1667ffffffffffffffff1611611949576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161194090614ea8565b60405180910390fd5b428260010160049054906101000a900467ffffffffffffffff1667ffffffffffffffff1611156119ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a590614f14565b60405180910390fd5b60008260010160006101000a81548163ffffffff021916908363ffffffff16021790555060008260010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600082600001600f6101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda38483604051611a7e9291906145f8565b60405180910390a260008373ffffffffffffffffffffffffffffffffffffffff1682604051611aac90614647565b60006040518083038185875af1925050503d8060008114611ae9576040519150601f19603f3d011682016040523d82523d6000602084013e611aee565b606091505b5050905080611b32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2990614f80565b60405180910390fd5b50505050565b60606000806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050809150600167ffffffffffffffff811115611b9b57611b9a613700565b5b604051908082528060200260200182016040528015611bc95781602001602082028036833780820191505090505b5092508183600081518110611be157611be061449c565b5b6020026020010181815250505050919050565b60006020528060005260406000206000915090508060000160009054906101000a90046dffffffffffffffffffffffffffff169080600001600e9054906101000a900460ff169080600001600f9054906101000a90046dffffffffffffffffffffffffffff16908060010160009054906101000a900463ffffffff16908060010160049054906101000a900467ffffffffffffffff16905085565b6000806000606080606060005a9050611ca6613428565b611cb460008b836001612470565b9550806040015196508960c001355a83611cce919061456f565b611cd89190614255565b9750611ce26128ec565b600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614611da4578573ffffffffffffffffffffffffffffffffffffffff16636076d43a8b8b6040518363ffffffff1660e01b8152600401611d51929190615104565b600060405180830381865afa158015611d6e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611d9791906151da565b8095508196508297505050505b600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0a90614c6e565b60405180910390fd5b50509295509295509295565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000828260000160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff16611e9d9190614255565b90506dffffffffffffffffffffffffffff8016811115611ef2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee9906152cd565b60405180910390fd5b808260000160006101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff16021790555050505050565b6000611f3a826128f2565b805190602001209050919050565b611fde81604051602401611f5c9190615331565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612934565b50565b61207781604051602401611ff59190613db9565b6040516020818303038152906040527f2c2ecbc2000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612934565b50565b6121108160405160240161208e9190615353565b6040516020818303038152906040527f32458eed000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612934565b50565b6000805a905060008086600001519050600061212e8261295d565b905060008260a001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561217a578260000151935061234e565b80935060008851111561234d57818702955060028081111561219f5761219e61536e565b5b8a60028111156121b2576121b161536e565b5b14612231578073ffffffffffffffffffffffffffffffffffffffff1663a9a2340984606001518c8b8a6040518563ffffffff1660e01b81526004016121f9939291906153e5565b600060405180830381600088803b15801561221357600080fd5b5087f1158015612227573d6000803e3d6000fd5b505050505061234c565b8073ffffffffffffffffffffffffffffffffffffffff1663a9a2340984606001518c8b8a6040518563ffffffff1660e01b8152600401612273939291906153e5565b600060405180830381600088803b15801561228d57600080fd5b5087f19350505050801561229f575060015b61234b576122ab615430565b806308c379a0141561230b57506122c0615452565b806122cb575061230d565b8b82826040517efa072b000000000000000000000000000000000000000000000000000000008152600401612302939291906154e8565b60405180910390fd5b505b8a816040517efa072b000000000000000000000000000000000000000000000000000000008152600401612342929190615572565b60405180910390fd5b5b5b5b5a850387019650818702955085896040015110156123a4578a816040517efa072b00000000000000000000000000000000000000000000000000000000815260040161239b9291906155fa565b60405180910390fd5b6000868a604001510390506123b98582611e1f565b60008060028111156123ce576123cd61536e565b5b8c60028111156123e1576123e061536e565b5b1490508460a0015173ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff168c602001517f33fd4d1f25a5461bea901784a6571de6debc16cd0831932c22c6969cd73ba99488602001518c89876040516124589493929190615636565b60405180910390a45050505050505095945050505050565b6000805a90506000846000015190506124898682612998565b6124928661090f565b85602001818152505060008661010001358760e001358360400151846060015185608001511717171790506effffffffffffffffffffffffffffff8016811115612511576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612508906156c7565b60405180910390fd5b60008061251d84612b40565b905061252c8a8a8a8a85612bb6565b809750819350505061253c6128ec565b6060600073ffffffffffffffffffffffffffffffffffffffff168560a0015173ffffffffffffffffffffffffffffffffffffffff161461258a576125838b8b8b8587612f68565b905061259d565b6040518060200160405280600081525090505b60005a87039050808b60a0013510156125f2578b8660a001516040517efa072b0000000000000000000000000000000000000000000000000000000081526004016125e9929190615759565b60405180910390fd5b828a604001818152505061260582613217565b8a60600181815250508a60c001355a8803018a608001818152505050505050505050949350505050565b6000805a905061263e81613221565b600061264d84606001516132ba565b90503073ffffffffffffffffffffffffffffffffffffffff16631d73275686806060019061267b9190614807565b87856040518563ffffffff1660e01b815260040161269c94939291906158b3565b6020604051808303816000875af19250505080156126d857506040513d601f19601f820116820180604052508101906126d59190615911565b60015b61271157600084608001515a846126ef919061456f565b6126f99190614255565b9050612709876002878585612113565b935050612716565b809350505b50509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561278f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127869061598a565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516127b590614647565b60006040518083038185875af1925050503d80600081146127f2576040519150601f19603f3d011682016040523d82523d6000602084013e6127f7565b606091505b505090508061280557600080fd5b505050565b6000808383600090601492612821939291906159b4565b9061282c9190615a33565b60601c9050600084846014908092612846939291906159b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505090506000602060008351602085016000875af190506000519350806128e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128da90615ade565b60405180910390fd5b50505092915050565b43600052565b6060366000838061014001906129089190614807565b915091508360208184030360405194506020810185016040528085528082602087013750505050919050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b6000808260c00151905060008360e00151905080821415612982578192505050612993565b61298e824883016132c4565b925050505b919050565b8160000160208101906129ab9190613c37565b816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050816020013581602001818152505081608001358160400181815250508160a001358160600181815250508160c001358160800181815250508160e001358160c00181815250508161010001358160e001818152505036600083806101200190612a4b9190614807565b915091506000828290501115612b00576014828290501015612aa2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a9990615b4a565b60405180910390fd5b8181600090601492612ab6939291906159b4565b90612ac19190615a33565b60601c8360a0019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050612b3a565b60008360a0019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b50505050565b600080600073ffffffffffffffffffffffffffffffffffffffff168360a0015173ffffffffffffffffffffffffffffffffffffffff161415612b83576001612b86565b60035b60ff1690506000836080015182856060015102856040015101019050612bab8461295d565b810292505050919050565b60008060005a9050600086600001519050612be081898060400190612bdb9190614807565b6132dd565b600173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415612c9a57806000015173ffffffffffffffffffffffffffffffffffffffff16633ad59dbc6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612c8157506040513d601f19601f82011682018060405250810190612c7e9190615b7f565b60015b612c915760009250829550612c99565b809350839650505b5b6000808260000151905060008360a001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612d05576000612ced83611580565b9050888111612cfe57808903612d01565b60005b9350505b8173ffffffffffffffffffffffffffffffffffffffff16630825d1fc85606001518d8d602001518d886040518663ffffffff1660e01b8152600401612d4d9493929190615bac565b600060405180830381600088803b158015612d6757600080fd5b5087f193505050508015612d79575060015b612e2757612d85615430565b806308c379a01415612de65750612d9a615452565b80612da55750612de8565b8c6000826040517efa072b000000000000000000000000000000000000000000000000000000008152600401612ddd939291906154e8565b60405180910390fd5b505b8b60006040517efa072b000000000000000000000000000000000000000000000000000000008152600401612e1e929190615c1b565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612f545760008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff169050808a1115612f18578d60006040517efa072b000000000000000000000000000000000000000000000000000000008152600401612f0f929190615ca3565b60405180910390fd5b8981038260000160006101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff16021790555050505b5a8503965050505050509550959350505050565b606060008460000151905060008160a00151905060008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000160009054906101000a90046dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff169050600082600001600e9054906101000a900460ff1690508061304a578a846040517efa072b000000000000000000000000000000000000000000000000000000008152600401613041929190615cdf565b60405180910390fd5b87821015613090578a846040517efa072b000000000000000000000000000000000000000000000000000000008152600401613087929190615d67565b60405180910390fd5b8782038360000160006101000a8154816dffffffffffffffffffffffffffff02191690836dffffffffffffffffffffffffffff16021790555060008786606001510390508473ffffffffffffffffffffffffffffffffffffffff1663f465c77e828d8d602001518d6040518563ffffffff1660e01b815260040161311693929190615da3565b60006040518083038160008887f19350505050801561315857506040513d6000823e3d601f19601f820116820180604052508101906131559190615de1565b60015b61320457613164615430565b806308c379a014156131c45750613179615452565b8061318457506131c6565b8c86826040517efa072b0000000000000000000000000000000000000000000000000000000081526004016131bb939291906154e8565b60405180910390fd5b505b8b856040517efa072b0000000000000000000000000000000000000000000000000000000081526004016131fb929190615c1b565b60405180910390fd5b8097505050505050505095945050505050565b6000819050919050565b6132b781604051602401613235919061366a565b6040516020818303038152906040527ff82c50f1000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612934565b50565b6060819050919050565b60008183106132d357816132d5565b825b905092915050565b60008282905014613423576000836000015173ffffffffffffffffffffffffffffffffffffffff163b14613346576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161333d90615e76565b60405180910390fd5b6000613352838361280a565b9050836000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146133c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133bd90615f08565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff163b1415613421576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161341890615f74565b60405180910390fd5b505b505050565b6040518060a0016040528061343b6134c1565b8152602001600080191681526020016000815260200160008152602001600081525090565b6040518060a0016040528060006dffffffffffffffffffffffffffff16815260200160001515815260200160006dffffffffffffffffffffffffffff168152602001600063ffffffff168152602001600067ffffffffffffffff1681525090565b604051806101000160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b600063ffffffff82169050919050565b61355f81613546565b811461356a57600080fd5b50565b60008135905061357c81613556565b92915050565b6000602082840312156135985761359761353c565b5b60006135a68482850161356d565b91505092915050565b600080fd5b600061016082840312156135cb576135ca6135af565b5b81905092915050565b6000602082840312156135ea576135e961353c565b5b600082013567ffffffffffffffff81111561360857613607613541565b5b613614848285016135b4565b91505092915050565b6000819050919050565b6136308161361d565b82525050565b600060208201905061364b6000830184613627565b92915050565b6000819050919050565b61366481613651565b82525050565b600060208201905061367f600083018461365b565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126136aa576136a9613685565b5b8235905067ffffffffffffffff8111156136c7576136c661368a565b5b6020830191508360018202830111156136e3576136e261368f565b5b9250929050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613738826136ef565b810181811067ffffffffffffffff8211171561375757613756613700565b5b80604052505050565b600061376a613532565b9050613776828261372f565b919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006137a68261377b565b9050919050565b6137b68161379b565b81146137c157600080fd5b50565b6000813590506137d3816137ad565b92915050565b6137e281613651565b81146137ed57600080fd5b50565b6000813590506137ff816137d9565b92915050565b6000610100828403121561381c5761381b6136ea565b5b613827610100613760565b90506000613837848285016137c4565b600083015250602061384b848285016137f0565b602083015250604061385f848285016137f0565b6040830152506060613873848285016137f0565b6060830152506080613887848285016137f0565b60808301525060a061389b848285016137c4565b60a08301525060c06138af848285016137f0565b60c08301525060e06138c3848285016137f0565b60e08301525092915050565b6138d88161361d565b81146138e357600080fd5b50565b6000813590506138f5816138cf565b92915050565b60006101808284031215613912576139116136ea565b5b61391c60a0613760565b9050600061392c84828501613805565b600083015250610100613941848285016138e6565b602083015250610120613956848285016137f0565b60408301525061014061396b848285016137f0565b606083015250610160613980848285016137f0565b60808301525092915050565b60008060008060006101c086880312156139a9576139a861353c565b5b600086013567ffffffffffffffff8111156139c7576139c6613541565b5b6139d388828901613694565b955095505060206139e6888289016138fb565b9350506101a086013567ffffffffffffffff811115613a0857613a07613541565b5b613a1488828901613694565b92509250509295509295909350565b60008083601f840112613a3957613a38613685565b5b8235905067ffffffffffffffff811115613a5657613a5561368a565b5b602083019150836020820283011115613a7257613a7161368f565b5b9250929050565b6000613a848261377b565b9050919050565b613a9481613a79565b8114613a9f57600080fd5b50565b600081359050613ab181613a8b565b92915050565b600080600060408486031215613ad057613acf61353c565b5b600084013567ffffffffffffffff811115613aee57613aed613541565b5b613afa86828701613a23565b93509350506020613b0d86828701613aa2565b9150509250925092565b60008060408385031215613b2e57613b2d61353c565b5b6000613b3c85828601613aa2565b9250506020613b4d858286016137f0565b9150509250929050565b613b6081613546565b82525050565b6000602082019050613b7b6000830184613b57565b92915050565b60008083601f840112613b9757613b96613685565b5b8235905067ffffffffffffffff811115613bb457613bb361368a565b5b602083019150836020820283011115613bd057613bcf61368f565b5b9250929050565b600080600060408486031215613bf057613bef61353c565b5b600084013567ffffffffffffffff811115613c0e57613c0d613541565b5b613c1a86828701613b81565b93509350506020613c2d86828701613aa2565b9150509250925092565b600060208284031215613c4d57613c4c61353c565b5b6000613c5b848285016137c4565b91505092915050565b60006dffffffffffffffffffffffffffff82169050919050565b613c8781613c64565b82525050565b60008115159050919050565b613ca281613c8d565b82525050565b613cb181613546565b82525050565b600067ffffffffffffffff82169050919050565b613cd481613cb7565b82525050565b60a082016000820151613cf06000850182613c7e565b506020820151613d036020850182613c99565b506040820151613d166040850182613c7e565b506060820151613d296060850182613ca8565b506080820151613d3c6080850182613ccb565b50505050565b600060a082019050613d576000830184613cda565b92915050565b60008060208385031215613d7457613d7361353c565b5b600083013567ffffffffffffffff811115613d9257613d91613541565b5b613d9e85828601613694565b92509250509250929050565b613db38161379b565b82525050565b6000602082019050613dce6000830184613daa565b92915050565b600060208284031215613dea57613de961353c565b5b6000613df884828501613aa2565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613e3681613651565b82525050565b6000613e488383613e2d565b60208301905092915050565b6000602082019050919050565b6000613e6c82613e01565b613e768185613e0c565b9350613e8183613e1d565b8060005b83811015613eb2578151613e998882613e3c565b9750613ea483613e54565b925050600181019050613e85565b5085935050505092915050565b60006020820190508181036000830152613ed98184613e61565b905092915050565b613eea81613c64565b82525050565b613ef981613c8d565b82525050565b613f0881613cb7565b82525050565b600060a082019050613f236000830188613ee1565b613f306020830187613ef0565b613f3d6040830186613ee1565b613f4a6060830185613b57565b613f576080830184613eff565b9695505050505050565b613f6a81613c8d565b8114613f7557600080fd5b50565b600081359050613f8781613f61565b92915050565b60008060408385031215613fa457613fa361353c565b5b600083013567ffffffffffffffff811115613fc257613fc1613541565b5b613fce858286016135b4565b9250506020613fdf85828601613f78565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015614023578082015181840152602081019050614008565b83811115614032576000848401525b50505050565b600061404382613fe9565b61404d8185613ff4565b935061405d818560208601614005565b614066816136ef565b840191505092915050565b600060c082019050614086600083018961365b565b614093602083018861365b565b6140a06040830187613daa565b81810360608301526140b28186614038565b905081810360808301526140c68185614038565b905081810360a08301526140da8184614038565b9050979650505050505050565b6000819050919050565b600061410c61410761410284613c64565b6140e7565b613651565b9050919050565b61411c816140f1565b82525050565b60006020820190506141376000830184614113565b92915050565b600082825260208201905092915050565b7f756e7374616b652064656c617920746f6f206c6f770000000000000000000000600082015250565b600061418460158361413d565b915061418f8261414e565b602082019050919050565b600060208201905081810360008301526141b381614177565b9050919050565b7f63616e6e6f7420646563726561736520756e7374616b652074696d6500000000600082015250565b60006141f0601c8361413d565b91506141fb826141ba565b602082019050919050565b6000602082019050818103600083015261421f816141e3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061426082613651565b915061426b83613651565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156142a05761429f614226565b5b828201905092915050565b7f7374616b652076616c756520746f6f206c6f7700000000000000000000000000600082015250565b60006142e160138361413d565b91506142ec826142ab565b602082019050919050565b60006020820190508181036000830152614310816142d4565b9050919050565b7f7374616b65206f766572666c6f77000000000000000000000000000000000000600082015250565b600061434d600e8361413d565b915061435882614317565b602082019050919050565b6000602082019050818103600083015261437c81614340565b9050919050565b600061439e61439961439484613546565b6140e7565b613651565b9050919050565b6143ae81614383565b82525050565b60006040820190506143c9600083018561365b565b6143d660208301846143a5565b9392505050565b60006060820190506143f26000830186613627565b6143ff6020830185613daa565b61440c604083018461365b565b949350505050565b600081905092915050565b82818337600083830152505050565b600061443a8385614414565b935061444783858461441f565b82840190509392505050565b600061446082848661442e565b91508190509392505050565b6000604082019050614481600083018561365b565b81810360208301526144938184614038565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b600082356001610160038336030381126144f7576144f66144cb565b5b80830191505092915050565b7f576974686472617720616d6f756e7420746f6f206c6172676500000000000000600082015250565b600061453960198361413d565b915061454482614503565b602082019050919050565b600060208201905081810360008301526145688161452c565b9050919050565b600061457a82613651565b915061458583613651565b92508282101561459857614597614226565b5b828203905092915050565b60006145be6145b96145b48461377b565b6140e7565b61377b565b9050919050565b60006145d0826145a3565b9050919050565b60006145e2826145c5565b9050919050565b6145f2816145d7565b82525050565b600060408201905061460d60008301856145e9565b61461a602083018461365b565b9392505050565b50565b6000614631600083614414565b915061463c82614621565b600082019050919050565b600061465282614624565b9150819050919050565b7f6661696c656420746f2077697468647261770000000000000000000000000000600082015250565b600061469260128361413d565b915061469d8261465c565b602082019050919050565b600060208201905081810360008301526146c181614685565b9050919050565b6000823560016060038336030381126146e4576146e36144cb565b5b80830191505092915050565b6000808335600160200384360303811261470d5761470c6144cb565b5b80840192508235915067ffffffffffffffff82111561472f5761472e6144d0565b5b60208301925060208202360383131561474b5761474a6144d5565b5b509250929050565b600061475e82613651565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561479157614790614226565b5b600182019050919050565b60006147a78261379b565b9050919050565b6147b78161479c565b81146147c257600080fd5b50565b6000813590506147d4816147ae565b92915050565b6000602082840312156147f0576147ef61353c565b5b60006147fe848285016147c5565b91505092915050565b60008083356001602003843603038112614824576148236144cb565b5b80840192508235915067ffffffffffffffff821115614846576148456144d0565b5b602083019250600182023603831315614862576148616144d5565b5b509250929050565b600082825260208201905092915050565b6000819050919050565b600061489460208401846137c4565b905092915050565b6148a58161379b565b82525050565b60006148ba60208401846137f0565b905092915050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126148ee576148ed6148cc565b5b83810192508235915060208301925067ffffffffffffffff821115614916576149156148c2565b5b60018202360384131561492c5761492b6148c7565b5b509250929050565b600082825260208201905092915050565b60006149518385614934565b935061495e83858461441f565b614967836136ef565b840190509392505050565b600061016083016149866000840184614885565b614993600086018261489c565b506149a160208401846148ab565b6149ae6020860182613e2d565b506149bc60408401846148d1565b85830360408701526149cf838284614945565b925050506149e060608401846148d1565b85830360608701526149f3838284614945565b92505050614a0460808401846148ab565b614a116080860182613e2d565b50614a1f60a08401846148ab565b614a2c60a0860182613e2d565b50614a3a60c08401846148ab565b614a4760c0860182613e2d565b50614a5560e08401846148ab565b614a6260e0860182613e2d565b50614a716101008401846148ab565b614a7f610100860182613e2d565b50614a8e6101208401846148d1565b858303610120870152614aa2838284614945565b92505050614ab46101408401846148d1565b858303610140870152614ac8838284614945565b925050508091505092915050565b6000614ae28383614972565b905092915050565b60008235600161016003833603038112614b0757614b066148cc565b5b82810191505092915050565b6000602082019050919050565b6000614b2c838561486a565b935083602084028501614b3e8461487b565b8060005b87811015614b82578484038952614b598284614aea565b614b638582614ad6565b9450614b6e83614b13565b925060208a01995050600181019050614b42565b50829750879450505050509392505050565b6000614ba08385613ff4565b9350614bad83858461441f565b614bb6836136ef565b840190509392505050565b60006040820190508181036000830152614bdc818688614b20565b90508181036020830152614bf1818486614b94565b905095945050505050565b7f6d7573742062652063616c6c6564206f66662d636861696e207769746820667260008201527f6f6d3d7a65726f2d616464720000000000000000000000000000000000000000602082015250565b6000614c58602c8361413d565b9150614c6382614bfc565b604082019050919050565b60006020820190508181036000830152614c8781614c4b565b9050919050565b7f6e6f74207374616b656400000000000000000000000000000000000000000000600082015250565b6000614cc4600a8361413d565b9150614ccf82614c8e565b602082019050919050565b60006020820190508181036000830152614cf381614cb7565b9050919050565b7f616c726561647920756e7374616b696e67000000000000000000000000000000600082015250565b6000614d3060118361413d565b9150614d3b82614cfa565b602082019050919050565b60006020820190508181036000830152614d5f81614d23565b9050919050565b6000614d7182613cb7565b9150614d7c83613cb7565b92508267ffffffffffffffff03821115614d9957614d98614226565b5b828201905092915050565b6000614dbf614dba614db584613cb7565b6140e7565b613651565b9050919050565b614dcf81614da4565b82525050565b6000602082019050614dea6000830184614dc6565b92915050565b7f4e6f207374616b6520746f207769746864726177000000000000000000000000600082015250565b6000614e2660148361413d565b9150614e3182614df0565b602082019050919050565b60006020820190508181036000830152614e5581614e19565b9050919050565b7f6d7573742063616c6c20756e6c6f636b5374616b652829206669727374000000600082015250565b6000614e92601d8361413d565b9150614e9d82614e5c565b602082019050919050565b60006020820190508181036000830152614ec181614e85565b9050919050565b7f5374616b65207769746864726177616c206973206e6f74206475650000000000600082015250565b6000614efe601b8361413d565b9150614f0982614ec8565b602082019050919050565b60006020820190508181036000830152614f2d81614ef1565b9050919050565b7f6661696c656420746f207769746864726177207374616b650000000000000000600082015250565b6000614f6a60188361413d565b9150614f7582614f34565b602082019050919050565b60006020820190508181036000830152614f9981614f5d565b9050919050565b60006101608301614fb46000840184614885565b614fc1600086018261489c565b50614fcf60208401846148ab565b614fdc6020860182613e2d565b50614fea60408401846148d1565b8583036040870152614ffd838284614945565b9250505061500e60608401846148d1565b8583036060870152615021838284614945565b9250505061503260808401846148ab565b61503f6080860182613e2d565b5061504d60a08401846148ab565b61505a60a0860182613e2d565b5061506860c08401846148ab565b61507560c0860182613e2d565b5061508360e08401846148ab565b61509060e0860182613e2d565b5061509f6101008401846148ab565b6150ad610100860182613e2d565b506150bc6101208401846148d1565b8583036101208701526150d0838284614945565b925050506150e26101408401846148d1565b8583036101408701526150f6838284614945565b925050508091505092915050565b6000604082019050818103600083015261511e8185614fa0565b905061512d6020830184613ef0565b9392505050565b600080fd5b600067ffffffffffffffff82111561515457615153613700565b5b61515d826136ef565b9050602081019050919050565b600061517d61517884615139565b613760565b90508281526020810184848401111561519957615198615134565b5b6151a4848285614005565b509392505050565b600082601f8301126151c1576151c0613685565b5b81516151d184826020860161516a565b91505092915050565b6000806000606084860312156151f3576151f261353c565b5b600084015167ffffffffffffffff81111561521157615210613541565b5b61521d868287016151ac565b935050602084015167ffffffffffffffff81111561523e5761523d613541565b5b61524a868287016151ac565b925050604084015167ffffffffffffffff81111561526b5761526a613541565b5b615277868287016151ac565b9150509250925092565b7f6465706f736974206f766572666c6f7700000000000000000000000000000000600082015250565b60006152b760108361413d565b91506152c282615281565b602082019050919050565b600060208201905081810360008301526152e6816152aa565b9050919050565b600081519050919050565b6000615303826152ed565b61530d818561413d565b935061531d818560208601614005565b615326816136ef565b840191505092915050565b6000602082019050818103600083015261534b81846152f8565b905092915050565b60006020820190506153686000830184613ef0565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600381106153ae576153ad61536e565b5b50565b60008190506153bf8261539d565b919050565b60006153cf826153b1565b9050919050565b6153df816153c4565b82525050565b60006060820190506153fa60008301866153d6565b818103602083015261540c8185614038565b905061541b604083018461365b565b949350505050565b60008160e01c9050919050565b600060033d111561544f5760046000803e61544c600051615423565b90505b90565b600060443d1015615462576154e5565b61546a613532565b60043d036004823e80513d602482011167ffffffffffffffff821117156154925750506154e5565b808201805167ffffffffffffffff8111156154b057505050506154e5565b80602083010160043d0385018111156154cd5750505050506154e5565b6154dc8260200185018661372f565b82955050505050505b90565b60006060820190506154fd600083018661365b565b61550a6020830185613daa565b818103604083015261551c81846152f8565b9050949350505050565b7f706f73744f702072657665727400000000000000000000000000000000000000600082015250565b600061555c600d8361413d565b915061556782615526565b602082019050919050565b6000606082019050615587600083018561365b565b6155946020830184613daa565b81810360408301526155a58161554f565b90509392505050565b7f70726566756e642062656c6f772061637475616c476173436f73740000000000600082015250565b60006155e4601b8361413d565b91506155ef826155ae565b602082019050919050565b600060608201905061560f600083018561365b565b61561c6020830184613daa565b818103604083015261562d816155d7565b90509392505050565b600060808201905061564b600083018761365b565b615658602083018661365b565b615665604083018561365b565b6156726060830184613ef0565b95945050505050565b7f6761732076616c756573206f766572666c6f7700000000000000000000000000600082015250565b60006156b160138361413d565b91506156bc8261567b565b602082019050919050565b600060208201905081810360008301526156e0816156a4565b9050919050565b7f55736564206d6f7265207468616e20766572696669636174696f6e4761734c6960008201527f6d69740000000000000000000000000000000000000000000000000000000000602082015250565b600061574360238361413d565b915061574e826156e7565b604082019050919050565b600060608201905061576e600083018561365b565b61577b6020830184613daa565b818103604083015261578c81615736565b90509392505050565b610100820160008201516157ac600085018261489c565b5060208201516157bf6020850182613e2d565b5060408201516157d26040850182613e2d565b5060608201516157e56060850182613e2d565b5060808201516157f86080850182613e2d565b5060a082015161580b60a085018261489c565b5060c082015161581e60c0850182613e2d565b5060e082015161583160e0850182613e2d565b50505050565b6158408161361d565b82525050565b6101808201600082015161585d6000850182615795565b506020820151615871610100850182615837565b506040820151615885610120850182613e2d565b506060820151615899610140850182613e2d565b5060808201516158ad610160850182613e2d565b50505050565b60006101c08201905081810360008301526158cf818688614b94565b90506158de6020830185615846565b8181036101a08301526158f18184614038565b905095945050505050565b60008151905061590b816137d9565b92915050565b6000602082840312156159275761592661353c565b5b6000615935848285016158fc565b91505092915050565b7f696e76616c69642062656e656669636961727900000000000000000000000000600082015250565b600061597460138361413d565b915061597f8261593e565b602082019050919050565b600060208201905081810360008301526159a381615967565b9050919050565b600080fd5b600080fd5b600080858511156159c8576159c76159aa565b5b838611156159d9576159d86159af565b5b6001850283019150848603905094509492505050565b600082905092915050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b600082821b905092915050565b6000615a3f83836159ef565b82615a4a81356159fa565b92506014821015615a8a57615a857fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802615a26565b831692505b505092915050565b7f696e6974436f6465206661696c65640000000000000000000000000000000000600082015250565b6000615ac8600f8361413d565b9150615ad382615a92565b602082019050919050565b60006020820190508181036000830152615af781615abb565b9050919050565b7f696e76616c6964207061796d6173746572416e64446174610000000000000000600082015250565b6000615b3460188361413d565b9150615b3f82615afe565b602082019050919050565b60006020820190508181036000830152615b6381615b27565b9050919050565b600081519050615b79816137ad565b92915050565b600060208284031215615b9557615b9461353c565b5b6000615ba384828501615b6a565b91505092915050565b60006080820190508181036000830152615bc68187614fa0565b9050615bd56020830186613627565b615be26040830185613daa565b615bef606083018461365b565b95945050505050565b6000615c0560008361413d565b9150615c1082614621565b600082019050919050565b6000606082019050615c30600083018561365b565b615c3d6020830184613daa565b8181036040830152615c4e81615bf8565b90509392505050565b7f77616c6c6574206469646e2774207061792070726566756e6400000000000000600082015250565b6000615c8d60198361413d565b9150615c9882615c57565b602082019050919050565b6000606082019050615cb8600083018561365b565b615cc56020830184613daa565b8181036040830152615cd681615c80565b90509392505050565b6000606082019050615cf4600083018561365b565b615d016020830184613daa565b8181036040830152615d1281614cb7565b90509392505050565b7f7061796d6173746572206465706f73697420746f6f206c6f7700000000000000600082015250565b6000615d5160198361413d565b9150615d5c82615d1b565b602082019050919050565b6000606082019050615d7c600083018561365b565b615d896020830184613daa565b8181036040830152615d9a81615d44565b90509392505050565b60006060820190508181036000830152615dbd8186614fa0565b9050615dcc6020830185613627565b615dd9604083018461365b565b949350505050565b600060208284031215615df757615df661353c565b5b600082015167ffffffffffffffff811115615e1557615e14613541565b5b615e21848285016151ac565b91505092915050565b7f73656e64657220616c726561647920636f6e7374727563746564000000000000600082015250565b6000615e60601a8361413d565b9150615e6b82615e2a565b602082019050919050565b60006020820190508181036000830152615e8f81615e53565b9050919050565b7f73656e64657220646f65736e2774206d6174636820696e6974436f646520616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000615ef260258361413d565b9150615efd82615e96565b604082019050919050565b60006020820190508181036000830152615f2181615ee5565b9050919050565b7f696e6974436f6465206661696c656420746f206372656174652073656e646572600082015250565b6000615f5e60208361413d565b9150615f6982615f28565b602082019050919050565b60006020820190508181036000830152615f8d81615f51565b905091905056fea26469706673582212208addda0544987f7a9824b18bd497b7afe098b10463fe6f24ed242f01f364b22e64736f6c634300080c0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000000000000000000000000000000000000000005

-----Decoded View---------------
Arg [0] : _paymasterStake (uint256): 50000000000000000
Arg [1] : _unstakeDelaySec (uint32): 5

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000b1a2bc2ec50000
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000005


Block Transaction Gas Used Reward
view all blocks ##produced##

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.